这次编程作业是对数组的一个练习,在使用数组时候,同学们要特别注意数组元素的下标范围,防止越界访问,数组的定义方式,数组应该是定义时就确定好了数组能够容纳的元素个数,以下为各个题的情况。
-
因初始数组设置的空间不够大,例如数组初始化为a[20],当输入的成绩个数大于数组可以存储的成绩个数时就会发生错误,因为题目中的n不会大于100,直接设置数组大小为100就可。
数据类型定义错误
-
对于成绩的和也要用一个double类型来存储,如果用int,那么即使平均数定义的是double类型,最后输出的结果也是一个整数保留了两位小数(例如输入样例,输出的结果就不是81.80,而是81.00)。double除以n才能有两位小数,int除以n的结果依然是整数,就算强制类型转化,小数位也全是0。
类型说明符错误
-
对于double类型,scanf的说明符只能是%lf,printf的说明符可以是%lf或者%llf(%llf是long double的scanf的说明符),同理对于int型scanf的说明符只能是%d,而不能是%lf,不能再读取时就将int型转化为double型。
段错误
-
对于数组定义如int a[n],n必须是一个知道的值,不能写出int n,a[n],这样的n不确定,无法分配数组的内存空间。
7-37
段错误
-
同7-36中的段错误一致。对于这道题,因为n和m题目中都是给定范围的,直接定义两个数组为a[1000]和b[100]即可。
算法错误
-
简单说一下这道题的算法以及大家容易出错的点。主题是两个循环嵌套。首先是遍历b数组,然后是遍历a数组,因为是在a数组中找b数组中的每个数。首先注意一个特殊情况,就是a数组只有一个数,这时候就算找到了相等的数,由于相邻没有数,这时候输出的结果全是NULL,大部分部分错误90分的提交都是少考虑了这一种情况。其次a数组的数大于1,如果是匹配第一个或者最后一个数,这时候只输出一个值,这是需要注意的第二个点;其他情况匹配都是输出两个值。当对于b数组的一个数遍历完a数组后没有找到匹配的数,输出NULL。
7-38
逻辑错误:
-
把所有偶数移到奇数,但不用更改偶数的顺序,所有的偶数序列顺序在运行前后是一致的。
算法错误
-
要得到一个偶数全在奇数前面的数组,本题一个简单的算法就是,定义一个新数组,遍历两边原数组,第一遍遇到偶数就加入到新数组,第二遍遇到奇数加入新数组,然后将新数组输出。第二个算法就是不定义新数组,直接在原数组上运行,最多遍历n遍数组,每一遍遍历数组如果遇到一个数是偶数并且前一个数是奇数,调换两个数的位置,最后进行n遍操作之后得到的数组输出。第一种方法相较于第二种,时间复杂度低,空间复杂度高,是空间换时间的方式。
-
还有一种更简单的做法,也有同学这样做,遍历两遍原数组,第一遍遇到偶数输出,第二遍遇到奇数输出,要注意输出的格式,注意空格的位置,这种做法也可以过系统,但不符合题目得到一个新数组的要求。)
7-39
段错误
-
这道题是大家做的最好的一道题,基本没啥错误,但还是有一些定义数组时出现的错误,和7-36,7-37一样的段错误,题目已经给了n<=10,直接定义两个数组a[10],b[10]用来存放两个向量即可。
-
除此之外,出现的错误要么是很低级,很小的错误,要么是审题错误。
7-40
逻辑错误
-
if else 条件语句使用错误,else只会与最近的else匹配
-
遗漏了有些对应面值的钞票,导致结果错误
-
错误使用多分支if else if ,本题中应该使用循环结构,对于每种面值的钞票都要进行判断
-
在选择对应面值的钞票时,需要先进行判断能否选取,如果不能,则进行选取更小的对应面值的钞票
for (int i = 0; i < N; i++)
{
if (n / money[i] > 0)
{
count = n / money[i];
n -= count * money[i];
printf("%d:%d\n", money[i], count);
}
}
编译错误
-
c语言语法错误,如:缺少分号
-
printf 函数使用错误
段错误
-
数组访问越界
7-41
逻辑错误
-
题目的意思是将数组a的a[b[i]]与a[i]进行交换。
-
不能在同一个循环中同时进行数组元素的交换和输出操作,可能多次对数组中同一个位置进行交换操作。
-
数组下标访问错误,如果自定义使用数组下标1~n的范围,那么需要注意此时数组长度为 n + 1。
-
注意数组下标的范围。
输出格式错误
-
输出格式错误,输出了多余的空格
不建议这样写
int n;
scanf("%d",&n);
int A[n];
int B[n];
// 建议改为
int A[N];
编译错误
-
变量未定义就使用
-
缺少分号
段错误
-
数组访问越界,导致段错误
7-42
编译错误
-
头文件包含语句书写错误
逻辑错误
-
两个序列的输入结束标志为-1,注意结束标志的判断,注意最后一个结束标志-1不属于数组中的元素。
-
是否找到的逻辑条件判断错误, 由于逻辑结构错误,导致后面的查找结果覆盖了前面的查找结果,在解决存在性问题的时候需要注意后面查找对于前面查找的影响。
-
数组访问范围出错,注意数组下标从0开始,长度为n的数组有效下标为[0, n - 1]。
该题为字符串匹配问题,首先可以先判断数组A的长度是否大于等于数组B的长度,如果不满足这一点,B必然不是A的子数组,否则进行逐个字符匹配匹配,假设A的长度为n, B的长度为m,核心代码表示如下:
int match = 0; // 还未匹配
for (int i = 0; i <= n - m && !match; i++) // 如果 n < m的话,循环体内的语句不会被执行
{
// 匹配 A[i, m - 1] 与 B[0, m - 1]进行匹配
match = 1; // 假设可以匹配
for (int j = 0; j < m && match; j++)
{
// 不匹配
if (A[i + j] != B[j])
{
match = 0;
}
}
}
if (match == 1)
{}
else
{}
7-43
编译错误
-
使用了c++的头文件,请同学们不要使用c++头文件iostream。
段错误
-
scanf函数缺少取地址符&
-
else(n == 2)错误的语法
-
变量未定义就使用
逻辑错误
-
数组访问范围错误
长度为n的数组,如果从下标0开始存储数据,范围为[0, n- 1]。
-
题目的要求是寻找最长满足要求的子数组,有的同学没有对所有情况取最大值,而取的是最后一种情况。
-
数组访问越界
这个题目的思路为:输入长度为n的序列,题目答案的最小值为1,我们可以从数组第二个元素开始循环遍历,每个元素与它前一个元素进行比较,代码如下:
int max_count = 1; // 答案至少为1, 单个元素的长度为1
int array[1000];
// input the array 数组进行输入
int count = 1; // 相同元素组成的子数组的长度
for (int i = 1; i < n; i++) // 数组序列[1, n-1]个元素进行遍历
{
if (array[i] == array[i - 1])
{
count++;
}
else
{
count = 1;
}
if (max_count < count) // 使用max_count来存储符合条件的最大值
{
max_count = count; // max_count
}
}