文章目录
A+B Problem(高精)
题目描述
高精度加法,相当于 a+b problem,不用考虑负数。
输入格式
分两行输入。 a , b ≤ 1 0 500 a,b \leq 10^{500} a,b≤10500。
输出格式
输出只有一行,代表 a + b a+b a+b 的值。
样例 #1
样例输入 #1
1
1
样例输出 #1
2
样例 #2
样例输入 #2
1001
9099
样例输出 #2
10100
提示
20 % 20\% 20% 的测试数据, 0 ≤ a , b ≤ 1 0 9 0\le a,b \le10^9 0≤a,b≤109;
40 % 40\% 40% 的测试数据, 0 ≤ a , b ≤ 1 0 18 0\le a,b \le10^{18} 0≤a,b≤1018。
分析
- 更加具体的分析在这里(点击查看高精度算法)
这里我凝练一下语言:用数组存储要操作的数,将各个数字拆开相加(注意进位),类比小学加法 - 讲一下这题的前导 0 的情况
因为我们是从后往前倒着输出的,并且一开始给数组c全赋值为 0 ,数组c的长度是数组a、b长度中最大的还要加一,就会出现这种情况:
a[0] a[1] a[2]
4 3 2
+ b[0] b[1]
1 2
c[0] c[1] c[2] c[3]
5 5 2 0
这样输出的结果是0255,所以要处理前导0,但也要注意0 + 0 = 0的情况
前导 0 处理代码模块:
lenc = lenc - 1; | 数组a、b放的都是0,lena=lenb=1
if (lenc >= 1) { | lenc = 1 + 1 = 2
while (c[lenc] == 0 && lenc >= 1) { | c[0] c[1]
lenc--; | 0 0
} | 那个while循环中的lenc>=1就是防
} | 止把c[0]的0也处理了
代码
#include <stdio.h>
#include <string.h>
//这里是写了个翻转方法
void reverse (int d[510], int len) {
int temp, mid = len/2;
for (int i = 0, j = len - 1; i < mid, j >= mid; i++, j--) {
temp = d[i];
d[i] = d[j];
d[j] = temp;
}
}
int main () {
int a[510] = {0}, b[510] = {0}, c[510] = {0};
char s1[510], s2[510];
scanf("%s", s1);
scanf("%s", s2);
int lena = strlen(s1);
int lenb = strlen(s2);
int lenc = (lena > lenb) ? (lena + 1) : (lenb + 1);
//将char的1转为int的1
for (int i = 0; i < lena; i++) {
a[i] = s1[i] - '0';
}
for (int i = 0; i < lenb; i++) {
b[i] = s2[i] - '0';
}
reverse(a, lena);
reverse(b, lenb);
//开始加了
for (int i = 0; i < lenc; i++) {
c[i] += a[i] + b[i];
c[i+1] = c[i] / 10;
c[i] = c[i] % 10;
}
//处理前导0
lenc = lenc - 1;
if (lenc >= 1) {
while (c[lenc] == 0 && lenc >= 1) {
lenc--;
}
}
//输出结果
for (int i = lenc; i >=0; i--) {
printf ("%d", c[i]);
}
return 0;
}
最后,如果我有遗漏的地方,欢迎大家评论补充,也欢迎大家斧正