寻找约数和最大的数:C语言代码错误排查求助
问题描述
题目要求:从标准输入读取一个自然数n,在所有小于n的自然数中,找出**约数和(计算时不包含数自身)**最大的那个数。
我编写了如下C语言代码,尝试遍历所有小于n的数(例如n=10时),此前曾出现溢出问题,现在得到的结果是9而非正确答案8,请问该如何修正?
原代码
#include <stdio.h> int main () { int n, n1, divisor = 0, sum = 0, largestSum = 0, final = 0; scanf("%d",&n); //for (int i = n; i > 0; i--) //{ n1= n- 1; while (n 1< n && n1 > 0) { divisor = n1 - 1; while (divisor> 0) { if (n1 % divisor== 0) { sum = sum + divisor; divisor--; if (sum > largestSum) { largestSum = sum; n1 = final; } } else if (n1 % divisor != 0) { divisor--; } n1--; } } //} printf("%d",final); }
问题分析与修正
你的代码存在几个关键错误,逐一修正如下:
- sum变量未重置:每次计算新数的约数和前,必须把sum清零,否则会累加之前所有数的约数和,导致计算结果完全错误。
- 结果赋值逻辑颠倒:当当前数的约数和sum超过largestSum时,应该把当前的数
n1赋值给final(保存结果),而不是把final赋值给n1——这直接导致final一直是初始值0,后续逻辑混乱才输出了9。 - 循环嵌套逻辑错误:
n1--被放在了内层的divisor循环中,导致一个数的约数还没遍历完,就直接跳到下一个数,遍历逻辑彻底混乱。应该把n1--放在外层循环的末尾,确保每个数的约数和计算完成后再换下一个数。 - 语法错误:
n 1< n多了空格,正确写法是n1 < n,否则编译器会报错。
修正后的完整代码
#include <stdio.h> int main() { int n, currentNum, divisor, sum, largestSum = 0, result = 0; scanf("%d", &n); // 遍历所有小于n的自然数,从1到n-1 for (currentNum = 1; currentNum < n; currentNum++) { sum = 0; // 每次计算新数前重置约数和 // 遍历当前数的所有可能约数(不包含自身),到currentNum/2即可,提升效率 for (divisor = 1; divisor <= currentNum / 2; divisor++) { if (currentNum % divisor == 0) { sum += divisor; } } // 更新最大约数和对应的数 if (sum > largestSum) { largestSum = sum; result = currentNum; } // 若约数和相同,保留较小的数(无特殊要求可省略此逻辑) else if (sum == largestSum && currentNum < result) { result = currentNum; } } printf("%d", result); return 0; }
补充说明
- 用for循环替代了混乱的while循环,逻辑更清晰易维护;
- 计算约数时只遍历到
currentNum/2,因为大于该值的数不可能是当前数的约数(除自身外),减少了循环次数; - 增加了约数和相同时的处理逻辑,可根据题目需求调整。
内容的提问来源于stack exchange,提问作者KingKendrick
相关产品推荐
相关产品推荐

