因为 unsigned long long 最大约 1.8×10¹⁹,无法表示几百位大数,必须用字符串模拟竖式加法:反转对齐低位,逐位相加并处理进位,避免索引越界和进位遗漏。

为什么不能直接用 long long 做大数相加
因为 C++ 原生整型最大只到 unsigned long long(约 1.8×10¹⁹),而竞赛题里动辄给几百位的十进制字符串,比如 "999999999999999999999999999999",直接转整数会溢出甚至未定义行为。必须用字符串存数字,手动模拟竖式加法。
字符串从右往左逐位相加的核心逻辑
关键不是“怎么写”,而是“怎么对齐、进位、拼接”。真实比赛里容易错在索引越界或进位漏处理。
- 两个字符串
a和b,先反转(std::reverse),让低位在前,方便用下标i对应个位、十位… - 用
carry = 0记进位,循环到两串都结束且carry == 0 - 每轮:取
a[i] - '0'(注意判i ),同理取b[i],加carry,再算新digit = sum % 10、carry = sum / 10 - 结果先 push_back 当前位,最后再反转回来
示例片段:
string add(string a, string b) {
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
string res;
int carry = 0;
for (int i = 0; i < a.size() || i < b.size() || carry; ++i) {
int sum = carry;
if (i < a.size()) sum += a[i] - '0';
if (i < b.size()) sum += b[i] - '0';
res.push_back('0' + sum % 10);
carry = sum / 10;
}
reverse(res.begin(), res.end());
return res;
}输入可能带前导零或空串,怎么安全处理
竞赛输入不保证干净。比如 "000123" 或 "" 或全零串 "0000",直接运算没问题,但输出要规范成无前导零(除非结果就是 0)。
立即学习“C++免费学习笔记(深入)”;
- 加法本身不怕前导零,反转后前面一堆
'0'只是多算几轮,不影响结果 - 但最终返回前要 trim:找到第一个非
'0'位置;如果找不到(全是零),返回"0" - 别用
stoi/stoll去清零——它们会溢出或抛异常
性能和边界要注意什么
单次加法 O(n),n 是较长字符串长度,没问题。但如果你在循环里反复 res = "x" + res(头插),就变成 O(n²),卡 TLE。
- 务必用
push_back+ 最后反转,不是字符串拼接 - 避免调用
substr或erase做截断,用双指针找有效起始位更稳 - 如果题目要多次加减乘除,建议封装成类,内部统一用逆序存储,省去反复反转
最常被忽略的是:进位变量要用 int,别用 bool——两位最大 9+9+1=19,进位最多是 1,但逻辑上 carry 是整数,写 bool 会掩盖后续扩展性(比如改造成乘法时进位可能达 81)。










