BM86 大数加法¶
中等通过率 38.96%python3核心代码模式样例通过牛客 AC字符串模拟
讲解章节:高精度与大整数
一句话
两串末尾对齐往前逐位相加,进位随手带到下一位。
解题思路¶
这题考什么¶
竖式加法的机器化表达。Python 的 int 是任意精度的, str(int(s or 0) + int(t or 0)) 一行就能通过;仍然手写竖式, 是因为这题真正考的是「位数超过机器字长时怎么加」—— C/C++/Java 没有内建的大整数类型,面试问的就是下面这套流程; 而同一副骨架换一条进位规则,就分别是大数乘法、进制转换与字符串减法。
竖式的三条规矩:
1. 低位对齐 —— 十进制的个位在字符串**末尾**,两个指针都从末尾起步
2. 逐位相加 —— cur = a 的当前位 + b 的当前位 + carry
3. 拆分进位 —— 本位写 cur % 10,进位 cur // 10 留给下一位
走一遍 "987" + "45":
i/j 指向 a位 b位 carry cur 写下 新 carry
7 / 5 7 5 0 12 2 1
8 / 4 8 4 1 13 3 1
9 / 越界 9 0 1 10 0 1
越界 / 越界 0 0 1 1 1 0 <- 循环条件带上 carry
低位在前攒出 "2301",整体反转得 "1032"
短串先越界,缺位当 0 补,不必先把两串补齐成等长,省一次拷贝。 高精度的完整讨论见 高精度与大整数。
数据规模与复杂度¶
两串长度各 <= 1e5,仅由 "0"~"9" 构成,时限「其他语言 2 秒」, 题面要求时间 O(n)。本解每位做一次加法与一次除模, 时间 O(n + m)、空间 O(max(n, m))(结果串本身)。 真正会超时的是在循环里写 res = ch + res:字符串不可变, 每次前插都要重新分配并拷贝整串,总搬运量约 1e5 * 1e5 / 2 = 5e9 个字符。 用列表收集、最后一次性 "".join 才是线性的。
坑在哪¶
- 循环条件是 i >= 0 或 j >= 0 或 carry,三者取或。漏掉 carry 会丢掉最高位的 进位("99" + "1" 输出成 "00");把 or 误写成 and,短串一走完循环就停, 长串剩下的高位会被整段丢掉。
- 结果是从低位往高位攒出来的,末尾必须整体反转,否则输出是逆序的数字串。
- 空串是合法输入(样例 2 是 "114514" + ""),按 0 处理。 即便不写开头那两个短路,「越界补 0」的逻辑本身也已覆盖这种情况。
- ord(c) - 48 与 chr(x + 48) 是字符与数值之间的互转,48 是字符 "0" 的 ASCII 码。 这里用它而不是 int(c) / str(x) 纯属常数优化,行为完全一致; 偏移量写错一位,输出就整体错位成别的字符。
- 进位只可能是 0 或 1:两个个位数加一个进位最大是 9 + 9 + 1 = 19, 所以 cur // 10 不会超过 1,不需要循环处理多重进位。
参考实现¶
[:octicons-arrow-left-16: BM85](BM85.md) [BM87 :octicons-arrow-right-16:](BM87.md)