超大整数加法 详细题解
2026-04-04 11:10:07
发布于:广东
5阅读
0回复
0点赞
这道题的核心难点是输入的数字超过了 C++ 所有基本数据类型(int、long long)的存储范围(最多 10000 位),普通的加法运算会直接溢出,所以必须用字符串模拟手工加法的方式来解决。
一、题目分析
- 输入:两个超长整数(最多 10000 位),以字符串形式输入;
- 输出:两个数的和;
- 核心思路:模拟我们手工列竖式加法的过程:低位对齐 → 逐位相加 → 处理进位 → 逆序输出结果。
二、解题步骤(核心逻辑)
我们做加法的手工步骤:
- 把两个数个位对齐(代码里用逆序存储实现);
- 从个位开始,逐位相加,满 10 进 1;
- 最后处理最高位的进位;
- 去掉前导 0,逆序输出结果。
三、完整代码逐行详解
#include <bits/stdc++.h> // 万能头文件,包含所有C++常用库
using namespace std;
// 全局变量:存储结果的数组,大小开足够大(100010)防止溢出
int s[100010];
int main () {
// 1. 用字符串存储两个超大整数(基本类型存不下)
string a, b;
cin >> a;
cin >> b;
// 2. 逆序存储:把字符串的低位(个位、十位)放到数组前面,方便从低位开始计算
// 处理第一个数 a,逆序存入数组 s
for (int i = 0; i < a.size(); i++) {
// a.size()-i-1 是从字符串最后一位(个位)开始取
// 字符转数字:'0'的ASCII码是48,减去'0'就能得到对应整数
s[i] = a[a.size() - i - 1] - '0';
}
// 处理第二个数 b,逆序加到数组 s 中(直接逐位累加)
for (int i = 0; i < b.size(); i++) {
s[i] += b[b.size() - i - 1] - '0';
}
// 3. 处理进位:满10进1
// len 记录结果的最大长度,初始等于较长的数字长度
int len = max(a.size(), b.size());
for (int i = 0; i < len; i++) {
if (s[i] >= 10) { // 当前位和大于等于10,需要进位
s[i + 1] += s[i] / 10; // 高位加进位值
s[i] %= 10; // 当前位保留余数
}
}
// 4. 处理最高位的额外进位(比如999+1=1000,会多一位)
if (s[len] > 0) len++;
// 5. 去掉前导0(防止输出 000123 这种情况,结果至少保留一个0)
while (len > 1 && s[len - 1] == 0) {
len--;
}
// 6. 逆序输出:数组存的是低位在前,输出要高位在前
for (int i = len - 1; i >= 0; i--) {
cout << s[i];
}
return 0;
}
四、关键知识点讲解
1. 为什么要用字符串存储?
int最多存 10位 数字,long long最多存 19位;- 题目要求最多 10000位,基本数据类型完全存不下,只能用字符串逐位存储。
2. 为什么要逆序存储?
手工加法是从右往左(低位到高位) 计算:
1234
+ 567
------
字符串里 1234 是正序:[1,2,3,4],低位在最后;
逆序后变成:[4,3,2,1],低位在最前,循环遍历就能直接从个位开始计算,非常方便。
3. 字符转数字的原理
字符 '5' 和数字 5 不是一个东西:
- 字符
'0'的 ASCII 码是 48,'1'是49……'9是57; - 所以
字符 - '0'就能得到对应的数字:'5' - '0' = 5。
4. 进位处理逻辑
- 每一位相加结果 ≥10 时,除以10得到进位值,加到下一位;
- 对10取余,保留当前位的数字;
- 最后检查最高位是否有进位,有就把长度+1。
5. 去掉前导0
比如计算 0001 + 0002 = 0003,我们需要输出 3 而不是 0003:
- 循环判断:如果长度>1 且最高位是0,就把长度减1;
- 保证结果至少有一个数字(不会把
0删掉)。
五、简化版代码(无多余函数,更易理解)
你原始代码里的 cmp 函数是减法用的,加法完全不需要,这是最简版:
#include <bits/stdc++.h>
using namespace std;
int res[100010];
int main() {
string a, b;
cin >> a >> b;
// 逆序存入
for (int i = 0; i < a.size(); i++) res[i] = a[a.size()-i-1] - '0';
for (int i = 0; i < b.size(); i++) res[i] += b[b.size()-i-1] - '0';
// 处理进位
int len = max(a.size(), b.size());
for (int i = 0; i < len; i++) {
res[i+1] += res[i]/10;
res[i] %= 10;
}
if (res[len]) len++;
// 去前导0 + 输出
while (len > 1 && res[len-1] == 0) len--;
for (int i = len-1; i >= 0; i--) cout << res[i];
return 0;
}
六、输入输出样例演示
输入:
2
1
执行过程:
- 逆序存储:
res[0]=2,res[0] +=1 → res[0]=3; - 无进位;
- 逆序输出:
3。
输出:
3
总结
- 超大数运算核心:用字符串存储,数组模拟计算;
- 加法固定模板:逆序存储 → 逐位相加 → 处理进位 → 逆序输出;
- 本题不需要比较大小,直接相加即可,这是和大数减法的核心区别。
这里空空如也

有帮助,赞一个