高精度加法题解
题目传送门
一、题目描述
给定两个正整数(不含前导0),计算它们的和。整数的长度可能达到100000位,因此需要使用高精度计算方法。
二、题目分析
由于C++中的基本数据类型无法存储如此大的整数(如100000位的数字),我们需要使用字符串来存储这些大数,并模拟手工加法的方式进行计算。
三、解题思路 + 算法讲解
- 输入处理:将两个大数以字符串形式读入
- 逆序存储:将字符串转换为数字数组,并逆序存储(方便从低位开始计算)
- 逐位相加:从最低位开始,逐位相加并处理进位
- 处理最后进位:如果最高位相加后有进位,需要额外处理
- 结果输出:将结果数组逆序输出得到正确顺序的和
四、代码实现
#include <iostream>
#include <vector>
#include <string>
using namespace std;
string a, b; // 输入的两个大数,以字符串形式存储
vector<int> A, B; // 将字符串转换为数字后,存储在 vector 中(逆序存储)
// 高精度加法函数
vector<int> add(vector<int> &A, vector<int> &B) {
vector<int> C; // 存储结果的 vector
int t = 0; // 进位值,初始为 0
for (int i = 0; i < A.size() || i < B.size(); i++) { // 遍历 A 和 B 的每一位
if (i < A.size()) t += A[i]; // 如果 A 还有位数,加上 A 的当前位
if (i < B.size()) t += B[i]; // 如果 B 还有位数,加上 B 的当前位
C.push_back(t % 10); // 将当前位的和取模 10,存入结果 C
t /= 10; // 计算进位值
}
if (t) C.push_back(1); // 如果最后还有进位,将 1 存入结果 C
return C; // 返回结果
}
int main() {
// 输入两个大数
cin >> a >> b;
// 将字符串逆序存储到 vector 中(方便从低位到高位计算)
for (int i = a.size() - 1; i >= 0; i--) {
A.push_back(a[i] - '0'); // 将字符转换为数字并存入 A
}
for (int i = b.size() - 1; i >= 0; i--) {
B.push_back(b[i] - '0'); // 将字符转换为数字并存入 B
}
// 调用高精度加法函数
auto C = add(A, B);
// 输出结果(逆序输出,因为存储时是逆序的)
for (int i = C.size() - 1; i >= 0; i--) {
printf("%d", C[i]);
}
return 0;
}
五、重点细节
- 逆序存储:将数字逆序存储在vector中,这样可以从最低位开始计算,方便处理进位
- 进位处理:使用变量
t
来记录当前位的和以及进位值 - 最后进位:循环结束后需要检查是否还有进位未处理
- 字符转数字:通过
a[i] - '0'
将字符转换为对应的数字
六、复杂度分析
- 时间复杂度:O(n),其中n是两个数字中较长的位数。我们需要遍历每一位进行加法运算。
- 空间复杂度:O(n),用于存储输入的数字和结果。
七、总结
高精度加法是处理大数运算的基础算法,核心思想是模拟手工加法过程。通过逆序存储数字、逐位相加并处理进位,可以有效地解决大数相加的问题。这个算法是许多高精度运算(如减法、乘法等)的基础,掌握它对后续学习其他高精度算法很有帮助。