不能用pow(10,d)提取最后d位,因double精度限制导致d>15时结果失真,引发切分错误;应改用整数循环计算幂,如long long base=1; for(int i=0;i

直接用字符串拆分平方结果,别碰 pow 或浮点运算——大数下 pow(10, d) 会因 double 精度丢失导致切分错位,这是绝大多数实现翻车的根源。
为什么不能用 pow(10, d) 提取最后 d 位
当 d > 15 时,pow(10, d) 返回的 double 值无法精确表示整数(例如 pow(10, 16) 在 IEEE 754 下可能变成 9999999999999999 或 10000000000000002),后续用它做模运算或除法就会算错 left 和 right。卡普列加数判定依赖精确位数切分,一错全错。
- 正确做法是用整数循环计算幂:
long long base = 1; for(int i = 0; i - 或者干脆放弃数值法,全程用
std::to_string(sq)+substr——更直观、无溢出、天然规避浮点误差 - 若坚持数值法,必须确保
base是精确的10^d,且sq用long long存(n最大到 1e5 时,sq达 1e10)
isKaprekar 必须处理的三个边界情况
漏掉任意一个都会误判:1 不是“可有可无”的特例,而是定义明确接受的合法卡普列加数;右段为 "00" 这类字符串在转整数时自动变成 0,但逻辑上它合法(只要左段 + 0 == n);而左段为空字符串则必须跳过(否则 stoll("") 抛异常)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
n == 1:直接返回true(1*1 == 1,按约定视为成立) - 平方字符串长度为 1(如
n=3 → sq="9"):此时无法切分(需至少 2 位才能分左右),直接跳过所有i循环,返回false - 右段字符串以 '0' 开头但非全零(如
"0025"):stoll会正确转成 25,无需额外过滤——但若右段是"000",stoll得 0,也合法(只要左段等于n)
枚举切分点时的合法范围怎么定
不是“按原数位数切”,也不是“只切中间”,而是对平方字符串 s 的每个位置 i(从索引 1 到 len-1)尝试切:左段 s.substr(0, i),右段 s.substr(i)。右段必须非空(i ),左段允许为空(但实际中空字符串要跳过,因为 <code>stoll 会炸)。
- 循环写成
for(int i = 1; i ,不是 <code>i - 不要提前限制右段长度等于
n的位数——那是另一种变体(Kaprekar 的原始定义允许多种切法,主流判定采用“任意合法切分”) - 每轮都检查
left是否为空字符串,是则跳过;right用stoll转,不检查前导零(stoll自动处理)
最易被忽略的是:卡普列加数定义要求右段**数值上非负即可**,并不要求它“是正整数”;所以 right == 0 是合法分支,比如 n=10,sq=100,切为 "10" + "0" → 10 + 0 == 10,成立。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










