高精度加法的C++解决办法
题目描述:
对于输入的两个不超过100位数的非负整数,给出两数之和。
输入格式:
在两行中分别给出两个不超过100位数字的非负整数。
输出格式:
在一行中输出两数之和。
输入样例:
123
12
输出样例
135
题目解读:
难点:
相比于常规的A+Bproblem,此题非常规的点是这两个给定的A,B是不超过100位数字的非负整数,两个数据大小都超过了C及C++中的所有数据类型,作为不具备高精度加法的编程语言,我们就无法简单以A+B去解决这个问题。
解题思路:
利用小学二年级知识,我们可以逐位逐位相加,满十进一。由此,解题思路应运而生。
算法描述
- 利用两个字符数组接受输入的数字字符。
- 将字符串数组转换为整型数组并倒转数组。
- 逐位相加,并使用一个数组存储各位相加的数字。遵循满十进一规则。
- 输出结果。
代码实现
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char A[100] = { '\0' }, B[100] = { '\0' };
cin >> A;
cin >> B;
//分别计算字符数组A,B的长度a,b并记录一个较大值c
int a1 = strlen(A);
int b1 = strlen(B);
int c1 = a1 >= b1 ? a1 : b1;
int a[100] = { 0 }, b[100] = { 0 };
for (int i = 0; i < a1; i++)
{
a[i] = A[a1 - 1 - i] - 48;//实现字符向数字转换 并倒转整个数组
}
for (int i = 0; i < b1; i++)
{
b[i] = B[b1 - 1 - i] - 48;
}
int sum[101] = { 0 };//为什么sum的数组要多开一个长度呢?
for (int i = 0; i < 100; i++)
{
int item = a[i] + b[i];
sum[i] += item % 10;//对十取余,正常获取每位数字(即便它不需要进位)
sum[i + 1] = item / 10;//若满十则进一
}
if (sum[c1] != 0)//当在最高位进一时,若sum定义仍为一百的长度,可能会造成溢出,无法存储进位。
{
cout << sum[c1];
}
for (int i = c1 - 1; i >= 0; i--)//从高位到低位依序输出
{
cout << sum[i];
}
return 0;
}
问题:为什么统计sum时一个使用+=一个使用=?
for (int i = 0; i < 100; i++)
{
int item = a[i] + b[i];
sum[i] += item % 10;//对十取余,正常获取每位数字(即便它不需要进位)
sum[i + 1] = item / 10;//若满十则进一
}
因为,进位时,下一位永远是0(数组已全部初始化置0),我们可以简单地给它赋值为1,实现的操作与+=1相同;
然而,在计算当前位数时,有可能在计算上一位数时完成了进位操作,直接赋值就将上一次的进位1抵消掉了。
原题链接
https://www.luogu.com.cn/problem/P1601