用string模拟手工加法是最稳妥方案,因标准整型无法容纳超长整数,需从低位逐位计算并处理进位,结果逆序拼接后反转,兼顾效率、安全与扩展性。

用 string 模拟手工加法是最稳妥的方案
标准 int、long long 无法容纳超长整数(比如 1000 位),C++ 没有内置大整数类型,必须自己实现。直接操作 string 是最常用、最可控的方式——把数字当字符串读入,从低位到高位逐位模拟小学竖式加法,处理进位。
- 输入字符串需确保只含数字字符,且不带前导空格或符号(如需支持负数,得额外判断和分支)
- 两个字符串长度可能不同,必须从末尾对齐,不能直接按索引硬算
- 进位变量
carry初始为 0,每轮计算后更新,并在循环结束后单独处理最高位进位 - 结果应逆序拼接(先 push_back 个位,最后
reverse),避免频繁头部插入导致 O(n²) 开销
string addStrings(string num1, string num2) {
string res;
int i = num1.size() - 1, j = num2.size() - 1, carry = 0;
while (i >= 0 || j >= 0 || carry) {
int x = i >= 0 ? num1[i--] - '0' : 0;
int y = j >= 0 ? num2[j--] - '0' : 0;
int sum = x + y + carry;
res.push_back('0' + sum % 10);
carry = sum / 10;
}
reverse(res.begin(), res.end());
return res;
}
为什么不用 vector 存各位数字
有人习惯先把字符串转成 vector(每位一个整数),再运算。这没本质错误,但多了一次遍历和内存分配,且容易在边界上出错(比如忘记清空、索引越界)。而直接用 string 下标访问字符,减 '0' 转数字,既省空间又少出错点。
-
num1[i] - '0'是安全的,前提是已校验i >= 0;用vector反而要额外检查size()和索引范围 - 结果字符串可直接
push_back字符,比vector再转字符串更直白 - 如果后续还要做乘法或比较,
string表示也更容易扩展(比如去掉前导零用find_first_not_of('0'))
遇到前导零或空字符串怎么办
真实输入常含前导零(如 "000123")或全零(如 "000")。函数本身不处理这些,返回结果可能带前导零(比如 "000" + "000" → "000"),需要额外清理。
- 若要求严格输出无前导零,可在返回前截断:
res.erase(0, res.find_first_not_of('0')); - 但要注意全零情况:若
find_first_not_of返回string::npos,应手动设为"0" - 空字符串输入(
"")应视为非法,实际使用前建议加if (num1.empty() || num2.empty())校验
性能和边界注意点
该算法时间复杂度是 O(max(m,n)),空间也是 O(max(m,n)),已经是最优。但几个细节容易被忽略:
立即学习“C++免费学习笔记(深入)”;
- 不要用
stoi或stoll尝试转换中间段——哪怕只有 20 位也可能溢出long long - 不要用
+=拼接结果字符串(如res = char + res),这是 O(n) 操作,整体变 O(n²) - 如果输入可能含负号,不能简单套用此逻辑;得先判断符号,再分同号/异号调用加法或减法逻辑
- 连续多次大数运算时,建议封装成类(如
BigNum),重载+运算符,避免重复写相同逻辑
真正难的不是写出来,而是想到所有输入变体——空串、全零、长度差极大、纯 9 的组合(如 "999" + "1"),这些边界跑一遍测试用例比看十遍代码都管用。










