史密斯数是合数且其各位数字之和等于所有质因数(含重复)的各位数字之和;需先判断合数,再质因数分解并累加各因子数字和,最后比较相等。

什么是史密斯数?先看判定逻辑
史密斯数是一个合数(即非质数且大于1),其各位数字之和等于它的所有**质因数**(含重复)的各位数字之和。注意两点:必须是合数;质因数分解后要展开重复因子(比如 4 = 2 × 2,质因数数字和是 2 + 2 = 4,不是 2)。
怎么写一个可靠的 isSmithNumber 函数
核心分三步:判断是否为合数 → 分解质因数(带重复)→ 分别计算原数和质因数的各位数字和。关键细节:
-
n == 1或质数直接返回false(史密斯数定义排除质数和1) - 质因数分解时,用试除法从
2到sqrt(n)即可,剩余大于1的n是最后一个质因数 - 计算数字和用循环取余更稳,避免字符串转换带来的额外开销和 locale 依赖
示例片段(C++17):
int digitSum(int n) {
int s = 0;
while (n) { s += n % 10; n /= 10; }
return s;
}
<p>bool isSmithNumber(int n) {
if (n </p><pre class="brush:php;toolbar:false;">int sumPrimeFactors = 0, temp = n;
for (int f = 2; f * f 1) sumPrimeFactors += digitSum(temp); // 剩余大质因数
return sumOrig == sumPrimeFactors;}
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
常见错误:把质数或1当成史密斯数
很多实现漏掉合数检查,导致 2、3、5 等质数被误判。例如 digitSum(2) == 2,质因数只有 2,数字和也是 2,但史密斯数明确定义要求“合数”。
- 务必在函数开头加合数判断:
if (n -
isPrime要高效且正确:对2单独处理,奇数只试到sqrt(n),别忘了1和2的边界 - 不要用
n % 2 == 0就认为是合数——2是质数
性能与边界要注意什么
对单次判断,O(√n) 质因数分解足够快;但若批量判断(如找前100个史密斯数),可预筛合数+质数表加速。另外几个易忽略点:
-
int溢出风险:输入若接近INT_MAX,f * f可能溢出,建议用f 或 <code>long long f -
digitSum对0返回0,但史密斯数定义中n > 0,无需特殊处理 - 标准库无现成质因数分解,别试图用
std::factorize(不存在)
真正卡住人的往往不是算法,而是没读清“合数”这个前提,以及质因数要展开重复计数——比如 999 = 3×3×3×37,质因数数字和是 3+3+3+3+7 = 19,不是 3+37。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










