丑数判断代码异常:输入30返回false的原因咨询
丑数判断代码的问题分析与修复方案
直接导致30返回false的原因
你在is_ugly函数里的条件判断逻辑完全错误:
if (i != 2 || i != 3 || i != 5)
这个表达式对任何i都会成立——比如i=2时,i!=3是true,整个||结果就是true,所以会直接设置result=false并break,这就是输入30(质因数包含2)却返回false的核心原因。正确的逻辑应该是当质因数不是2、3、5中的任何一个时才判定非丑数,也就是用&&:
if (i != 2 && i != 3 && i != 5)
其他致命逻辑错误
1. is_prime函数的问题
- 初始值设置错误:比如
num=2时,循环i<=sqrt(2)不会执行,直接返回初始的false,但2是质数。正确的初始值应该设为true,默认是质数,直到找到因数才改为false。 - 循环内赋值逻辑错误:每次循环都会覆盖
result,比如num=15(不是质数),i=3时num%i==0,result设为false,但i=4时15%4!=0,result又被设为true,最后错误返回true。正确的做法是只要找到一个能整除的i,立刻返回false,无需继续循环。
2. is_ugly函数的逻辑缺陷
- 找到一个符合条件的质因数就break返回true,这会导致错误判断:比如
num=14(质因数2和7),当i=2时会直接返回true,但14不是丑数。必须检查所有质因数,只要存在一个非2/3/5的质因数,才返回false。 - 遍历所有因数的效率极低,完全没必要——丑数的判断可以用更简洁高效的方法:不断把数字除以2、3、5,直到无法整除,最后结果为1就是丑数。
修复后的代码
修复原逻辑的版本
#include <stdbool.h> #include <math.h> bool is_prime(unsigned int num) { if (num <= 1) return false; if (num == 2) return true; if (num % 2 == 0) return false; bool result = true; for (unsigned int i = 3; i <= sqrt(num); i += 2) { if (num % i == 0) { result = false; break; } } return result; } bool is_ugly(unsigned int num) { if (num == 1) return true; bool result = true; for (unsigned int i = 2; i <= num; i++) { if (num % i == 0) { if (is_prime(i)) { if (i != 2 && i != 3 && i != 5) { result = false; break; } } } } return result; } int main(void) { bool result = is_ugly(30); // 现在返回true return 0; }
推荐的高效实现版本
#include <stdbool.h> bool is_ugly(unsigned int num) { if (num == 0) return false; while (num % 2 == 0) num /= 2; while (num % 3 == 0) num /= 3; while (num % 5 == 0) num /= 5; return num == 1; } int main(void) { bool result = is_ugly(30); // 返回true bool result2 = is_ugly(14); // 返回false return 0; }
内容的提问来源于stack exchange,提问作者Gabriel Burzacchini
相关产品推荐
相关产品推荐

