数组元素乘任意数全相等的C语言错误代码排查
问题要求
给定正整数数组,允许对每个元素乘以任意正整数,操作后让所有元素值完全相等,输出最终相等的数值(取最小的可行值即可)。
样例参考:数组
{2,3,4,5},分别给各元素乘1800、1200、900、720后所有值统一为3600,对应样例输出为3600。
原错误代码
#include <stdio.h> bool EqualNumbers(int a[], int n) { int i, j; for ( i = 0; i < n; i++) { for(j = 0; j<n; j++) { while (a[i] % a[i]== 0) a[i] = a[i] * a[i]; } if (a[i] != a[0]) { return false; } } return true; } int main() { int j, m; scanf("%d", &m); int a[m]; for(j = 0; j < m; j++) { scanf("%d", &a[j]); } int n = sizeof(a) / sizeof(a[0]); if (EqualNumbers(a, n)) { for(j = 0; j < m; j++) { printf("%d", a[j]); } } return 0; }
原代码错误点梳理
- 核心算法完全错误:题目要求的最小可行相等值本质是数组所有元素的最小公倍数(LCM),原代码没有实现任何LCM计算逻辑,反而写了恒成立的判断条件
a[i] % a[i]==0进入死循环,让a[i]反复平方,会快速触发整数溢出得到无意义的乱值。 - 语法错误:C语言原生不支持
bool类型,必须引入<stdbool.h>头文件才能使用布尔类型,原代码缺失该头文件直接编译失败。 - 冗余错误逻辑:所有元素都是正整数时,永远可以通过乘以正整数得到统一值,不存在操作失败返回false的场景,原代码设计的布尔返回判断完全多余;另外已经通过输入拿到了数组长度
m,不需要额外用sizeof计算长度,且数组作为函数参数传参时会退化为指针,用sizeof(a)/sizeof(a[0])计算长度的写法本身就会得到错误结果。 - 输出逻辑错误:最终所有元素值完全相同,不需要循环遍历打印整个数组,原写法会连续输出重复数字,没有实际可读性。
修正后实现代码
#include <stdio.h> // 辗转相除法计算两个数的最大公约数 long long gcd(long long a, long long b) { while (b != 0) { long long temp = b; b = a % b; a = temp; } return a; } int main() { int m; scanf("%d", &m); int a[m]; for (int j = 0; j < m; j++) { scanf("%d", &a[j]); } // 迭代计算数组所有元素的最小公倍数 long long lcm = a[0]; for (int i = 1; i < m; i++) { // 先除后乘,避免中间值溢出 lcm = lcm / gcd(lcm, a[i]) * a[i]; } printf("%lld", lcm); return 0; }
实现说明
- 基于数论公式实现:两个正整数的最小公倍数 = 两数乘积 / 两数的最大公约数,迭代遍历数组即可算出整个数组的最小公倍数,也就是题目要求的最小相等值。
- 计算时先做除法再做乘法,同时用
long long类型存储公倍数结果,尽可能避免整数溢出问题,支持更大范围的输入计算。 - 去掉了原代码中无意义的多层循环和死循环逻辑,一次遍历即可得到结果,运行效率更高,输入样例
2 3 4 5时可正确输出3600,符合题目要求。
内容的提问来源于stack exchange,提问作者Sharif khan
相关产品推荐
相关产品推荐

