因为c++原生整型位宽固定,long long仅支持≤10¹⁸,无法存储数百位大数,必须用string模拟加法:逆序遍历、逐位相加、手动处理进位与对齐。

为什么不能直接用 int 或 long long 做大数加法
因为 C++ 原生整型有固定位宽,long long 最多撑到 1018 量级,而题目里动辄几百位的数字一进来就溢出——不是计算错,是根本存不下。这时候必须把数字当字符串处理,一位一位算,自己管进位、对齐、符号。
string 模拟加法:从低位开始逐位相加
核心思路是「逆序遍历 + 进位累加」,和手算完全一致。别想着正着扫,那样得反复在字符串头插字符,性能差还易错。
- 先把两个字符串
s1、s2反转(std::reverse),让个位在下标 0 - 用
i和j分别遍历,每次取s1[i] - '0'转成数字,加上进位carry - 结果当前位是
(a + b + carry) % 10,新进位是(a + b + carry) / 10 - 算完再把结果字符串反转回来
示例关键片段:
string add(string s1, string s2) {
reverse(s1.begin(), s1.end());
reverse(s2.begin(), s2.end());
string res;
int carry = 0;
for (int i = 0; i < s1.size() || i < s2.size() || carry; ++i) {
int a = (i < s1.size()) ? s1[i] - '0' : 0;
int b = (i < s2.size()) ? s2[i] - '0' : 0;
int sum = a + b + carry;
res.push_back('0' + sum % 10);
carry = sum / 10;
}
reverse(res.begin(), res.end());
return res;
}处理负数时别硬套加法逻辑
字符串模拟一旦涉及负号,直接套用上面的加法会出错——比如 "-123" + "45" 实际是减法。更稳妥的做法是:先判断符号组合,分三类处理:
立即学习“C++免费学习笔记(深入)”;
- 同号:去掉负号,按正数加法算,最后补负号
- 异号:转为减法,即用绝对值大的减小的,再决定最终符号
- 其中一方为负且长度短、数值小,容易在减法中借位失败——务必保证被减数不小于减数,否则先交换再算,最后加负号
简单判断符号可这样写:s[0] == '-';取绝对值就是 s[0] == '-' ? s.substr(1) : s。
容易漏掉的边界:前导零和空字符串
如果输入是 "0" 或 "000",按上述逻辑可能算出 "000" 或空结果。实际应统一归一化:
- 运算前先用
erase去掉前导零,但至少保留一位(防止全删成空) - 加法结果若全为零(如
"000"),最后应返回"0" - 特别注意:输入可能为空字符串,或只有负号(如
"-"),这些属于非法输入,但线上题库有时会塞进来,建议加基础校验
去前导零常用写法:s.erase(0, s.find_first_not_of('0')); if (s.empty()) s = "0";
大数加法真正麻烦的从来不是算法本身,而是符号、长度、零、空这四点交织时的组合判断——少一个分支,测试样例就卡在第 42 个。











