史密斯数是合数且其各位数字之和等于所有质因数(含重复)的各位数字之和;判定需先排除质数,再分别计算原数与质因数分解后各因子数字和是否相等。

什么是史密斯数?先看判定逻辑
史密斯数不是质数,但它的各位数字之和等于它所有质因数(含重复)的各位数字之和。比如 27:2+7=9;质因数分解是 3×3×3,3+3+3=9 → 是史密斯数。关键点有三个:合数、数字和相等、质因数要拆开每位加(不是加质因数本身,而是加它们的各位数字)。
怎么写一个可靠的 isSmithNumber 函数
核心步骤得按顺序来,跳步或顺序错就会漏判:
- 先用
isPrime判断是否为质数 —— 如果是,直接返回false(史密斯数必须是合数) - 计算原数的各位数字和:
digitSum(n),别忘了处理n == 0边界(但题设是正整数,可略) - 做质因数分解:从小到大试除,每次找到因子就累加它的各位数字和(比如因子是
25,加的是 2+5,不是加 25) - 注意重复因子:如
12 = 2×2×3,要分别对每个2计算数字和,不能只算一次
示例片段(关键逻辑):
int digitSum(int n) {
int s = 0;
while (n) { s += n % 10; n /= 10; }
return s;
}
<p>bool isSmithNumber(int n) {
if (isPrime(n)) return false;
int sumOrig = digitSum(n);
int sumFactors = 0;
int temp = n;
for (int i = 2; i * i 1) sumFactors += digitSum(temp); // 剩余大质因数
return sumOrig == sumFactors;
}</p>
isPrime 实现里最容易出错的地方
很多实现漏掉 1 和 2 的特判,或者循环上限写成 i 导致超时。正确写法必须:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
if (n (<code>1不是质数)if (n == 2) return true-
if (n % 2 == 0) return false(排除偶数) - 循环从
3开始,只试奇数,上限是i * i ,不是 <code>i
否则像 4 会被误判为质数,导致 isSmithNumber(4) 返回 false(错误:4 是合数,质因数是 2×2,数字和 4 == 2+2,应为 true)
测试时别忽略这些边界情况
史密斯数最小的是 4,接下来是 22、27、58……但容易翻车的点在于:
-
n = 1:不是合数,也不是质数,isSmithNumber必须返回false -
n = 6:质因数 2×3,数字和 6 ≠ 2+3=5 → 正确返回false -
n = 378:质因数含3、3、3、7,但有人会把3×3×3×7当成四个因子,却忘了digitSum(3)每次都是 3,不是加 3+3+3+7=16(那是错的),而是 3+3+3+7=16?不 —— 是 3+3+3+7 的各位数字和:3+3+3+7=16,但 16 的各位和是 1+6=7?不对!注意:史密斯数定义中“质因数的各位数字之和”,指的是每个质因数单独拆位相加,不是对乘积或和再拆。所以 3、3、3、7 都是个位数,和就是 3+3+3+7=16;原数 378 的各位和是 3+7+8=18 → 不等,所以 378 不是史密斯数(实际也不是)
真正易错的是质因数含多位数的情况,比如 22:2×11 → 数字和是 2 + (1+1) = 4,原数 2+2=4 → 成立。这里 11 必须拆成 1+1,不能当整体加。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










