这次编程作业是对数组的一个练习,在使用数组时候,同学们要特别注意数组元素的下标范围,防止越界访问,数组的定义方式,数组应该是定义时就确定好了数组能够容纳的元素个数,以下为各个题的情况。

 

7-36

部分错误

  • 因初始数组设置的空间不够大,例如数组初始化为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];

// 建议改为
#define N 100
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
  }
}

You have no rights to post comments