基于“楔形数(Sphenic数)有8个因数”的C代码错误排查求助
问题根源:混淆了“8个因数的数”与“楔形数”的定义
错误原因
楔形数的严格定义是三个不同质数的乘积(例如30=2×3×5),这类数确实有8个因数,但反过来,有8个因数的数并不都是楔形数。
56的因数是1、2、4、7、8、14、28、56,共8个,但它的质因数分解是2³×7——包含重复的质因数(2出现了3次),不符合楔形数的要求。
原代码的isSphenic函数仅通过n >=30和因数个数为8来判断,完全忽略了楔形数必须满足的「三个不同质数乘积」这一核心条件,导致误判。
错误定位
问题出在isSphenic函数的判断逻辑:
bool isSphenic(int n) { if (n >= 30 && countDivisor(n) == 8) { return true; } return false; }
这个条件只筛选了因数数量,没有验证质因数的组成是否符合要求。
修正方案
要正确判断楔形数,必须验证两个核心条件:
- 数可以分解为恰好3个不同的质数
- 每个质因数仅出现一次(即没有平方或更高次的质因数)
以下是修正后的完整代码,其中isSphenic_v2函数实现了正确的判断逻辑:
#include <stdio.h> #include <stdbool.h> #include <math.h> bool isSphenic_v2(int n) { if (n < 30) return false; // 最小楔形数是30 int uniquePrimeCount = 0; int temp = n; // 处理质因数2 if (temp % 2 == 0) { uniquePrimeCount++; temp /= 2; if (temp % 2 == 0) return false; // 2出现多次,不符合要求 while (temp % 2 == 0) temp /= 2; // 移除剩余的2因子 } // 处理奇数质因数 for (int i = 3; i <= sqrt(temp); i += 2) { if (temp % i == 0) { uniquePrimeCount++; temp /= i; if (temp % i == 0) return false; // 当前质数出现多次,不符合要求 while (temp % i == 0) temp /= i; // 移除剩余的当前因子 } } // 如果剩余的temp是大于2的质数,计入统计 if (temp > 2) { uniquePrimeCount++; } // 必须恰好有3个不同的质因数 return uniquePrimeCount == 3; } int main() { int n; printf("Enter a number: "); scanf("%d", &n); if (isSphenic_v2(n)) { printf("Sphenic number!"); } else { printf("Not a sphenic number!"); } return 0; }
测试验证
- 输入30 → 输出
Sphenic number!(正确) - 输入56 → 输出
Not a sphenic number!(正确) - 输入105(3×5×7)→ 输出
Sphenic number!(正确) - 输入128(2⁷)→ 输出
Not a sphenic number!(正确,虽有8个因数,但不符合楔形数定义)
内容的提问来源于stack exchange,提问作者ahnherin092
相关产品推荐
相关产品推荐

