第8次编程作业总结

 

    这次作业是对于递归的一次练习,主要出现的错误是编译错误和逻辑错误,在书写递归代码时候,大家犯的错主要有缺少递归终止条件、递归逻辑错误。如果递归缺少终止条件,则会无限递归,导致程序错误,递归是将原问题规模缩小,以便更好地解决原问题的一种方法,所以书写递归代码时候需要搞清楚原问题与一个规模更小问题之间的联系。 还有同学使用了迭代的方法解题,希望可以思考以下使用递归的思想来解决这些问题,还有同学们在写程序时候不要使用break, goto语句。以下为各个题目的错误情况。

6-8

  • 编译错误

    • 确实返回值或者函数返回错误,在n>0的时候,返回值为return fuc(n-1)+n*n*n;错写为return fuc(n)=fuc(n-1)+n*n*n;或者return fuc(n)=fuc(n)+n*n*n。

    • 应该是递归函数,而不能写出一个函数直接用循环算出。

    • n的三次方在计算机中是n*n*n,而不是n^3,这是数学表达式。

6-9

  • 答案错误

    • s少算了一个a,少了n等于0的情况,此时s=s+a+3*0;

  • 编译错误

    • 返回值return getSum(n-1,a)+a+3n而不是return getSum(int n-1,int a)+a+3*n。

  • 答案错误

    • 例如

    int getSum(int n , int a)
    {
         if(n>=0)
        {
             return a+3*n+getSum(n-1,a);
        }
    }
    这样写会确实n等于0情况下的返回值。

6-10

  • 答案错误

    • 没有考虑n=1只输入一个数的情况。

  • 逻辑错误

    • 首先函数的输入是n,代表还要读取的数的个数,递归的逻辑是如果n=1,就直接返回读取的值,否则n>1的时候读取的数与剩下n-1个数中最大的数 (findMax(n-1)) 相比,返回大的值。

6-11

  • 答案错误

    • 在n等于1或0时,返回的是n;很多错误是确实n等于0的返回值。

  • 段错误

     int convert(int n)
    {
    int a=(n%10)+convert(n/10)*2;
    if(n==0||n==1){
    return n;
    }else {
    return a;
    }
    }
    这样也是在n等于1或者0时返回错误。

6-12

  • 编译错误

    • 变量未定义就使用; 语句末尾少分号;

    • (int)(n / 2)为正确写法,错写成int(n / 2), 强制类型转换不必要,因为两个整型变量做运算后得到的依然是整型变量

  • 逻辑错误

    • 编写递归代码忽略了0这一情况导致递归无法终止,导致运行超时或答案错误

  • 逻辑错误

    • 0用二进制表示占1位,而不是0位,很多同学90分在于这一点错误。

    • 循环变量在循环中未被修改,导致运行超时(死循环)。

    • 在本题中有一些同学直接使用的迭代的方式来解题,希望同时也试试递归写法。

    • 本题的递归终止条件应该是n为0或n为1的时候,错写递归终止条件可能会导致递归无法结束,最后导致栈溢出,或者结果错误。

6-13

  • 逻辑错误

    • 递归终止条件书写错误,

  • 编译错误:

    • 函数题只需写函数体代码即可,多写的main函数代码会导致main函数重定义,导致编译错误。

    • 函数名拼写错误

    • 变量未定义就使用

  • 逻辑错误

    • c语言中^为异或运算符与数学中的幂运算运算符注意区分。

    • 递归终止条件错误,递归的终止条件本题应该为 if (n == 0) { return 1 + a}或者if (n == -1) { return 1};

    • 未控制好递归终止条件导致无限递归,报运行超时错误。

    • = 与 == 误用,导致递归无法结束

6-14

  • 编译错误

    • 语法错误

    • GCD(a,b) = GCD(b, a%b); 这一写法是错误的

  • 逻辑错误

    • if (a > b) GCD(a,b) 与 GCD(b, a % b)一样

    • 最大公因数的定义, 假设a,b的最大公因数为c, a % c == b % c == 0, 而不是 a % c == b % c。

  • 运行超时

    • 未使用辗转相除法可能会导致超时

    • 递归无递归终止条件

6-15

  • 编译错误

    • 缺少;

    • 函数无返回值却用于表达式计算

  • 段错误

    • 变量未定义就使用

    • printf("%d", &a); 输出的是变量a的地址

  • 逻辑错误

    • 递归逻辑错误

    • 递归缺少终止条件导致运行超时,因为递归无法进行回归

    • 这个题目中函数是没有返回值的,由于函数声明为void reverse(int n);

  • 输出格式错误

    • 未按照题目给出的格式进行输出

6-16

  • 编译错误

    • main函数重定义,书写函数的题,只需书写函数体代码即可,不用再重复写main函数,注意审题。

    • 强制类型转换的正确写法为(int)()而不是int()

    • 引入头文件写法错误 应该为#include<xxx.h>

    • 函数头书写错误,返回类型,参数列表

    • else之前缺少if

    • 变量未定义就使用,函数拼写错误

  • 逻辑错误

    • 递归结束条件书写错误

    • 递归逻辑错误

  • 本题的思路应该为:

    • 假设数字n进行素数分解

    • 第一次调用改函数时,打印n=

    • 递归终止条件为当前数字n为素数,直接输出n和换行。

    • 若不是素数,从大到小寻找一个素数i 使得 n % i == 0 , 打印i,递归的对于(n / i)进行素数分解。

    参考代码如下:

    int isPrime(int n)
    {
         int i = 2;
         while (i * i <= n && n % i != 0)
        {
             i++;
        }
         return i * i <= n  ? 0 : 1;
    }

    void printFactor(int num, int depth)
    {
    // 是否找到一个素数能使得 num % i == 0
         int isprime = 0;
         int i = 2;
    // 第一次调用printFactor
         if (depth == 1)
        {
             printf("%d=", num);
        }
    // 如果num为素数 递归结束
         if (isPrime(num))
        {
             printf("%d\n", num);
             return;
        }
     
    // 寻找一个素数i , 使得 num % i == 0
         while(i < num && !isprime)
        {
             if (isPrime(i) && num % i == 0)
            {
                 isprime = 1;
            }
             else
            {
                 i++;
            }
        }
         // 打印当前素数因子
         printf("%d*", i);
    // 递归对于 num / i 进行素数分解
         printFactor(num / i, depth + 1);
    }

You have no rights to post comments