用string模拟手工加法是最稳妥方案,因标准整型无法容纳超长整数,需从低位逐位计算并处理进位,结果逆序拼接后反转,兼顾效率、安全与扩展性。
标准 int、long long 无法容纳超长整数(比如 1000 位),C++ 没有内置大整数类型,必须自己实现。直接操作 string 是最常用、最可控的方式——把数字当字符串读入,从低位到高位逐位模拟小学竖式加法,处理进位。
carry 初始为 0,每轮计算后更新,并在循环结束后单独处理最高位进位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(每位一个整数),再运算。这没本质错误,但多了一次遍历和内存分配,且容易在边界上出错(比如忘记清空、索引越界)。而直接用 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)),已经是最优。但几个细节容易被忽略:
stoi 或 stoll 尝试转换中间段——哪怕只有 20 位也可能溢出 long long
+= 拼接结果字符串(如 res = char + res),这是 O(n) 操作,整体变 O(n²)BigNum),重载 + 运算符,避免重复写相同逻辑真正难的不是写出来,而是想到所有输入变体——空串、全零、长度差极大、纯 9 的组合(如 "999" + "1"),这些边界跑一遍测试用例比看十遍代码都管用。