计蒜客 T1098:大整数加法
题目
求两个不超过 200 位的非负整数的和。
输入格式
有两行,每行是一个不超过 200 位的非负整数,
可能有多余的前导 0。
输出格式
一行,即相加后的结果。结果里不能有多余的前导 0,
即如果结果是 342,那么就不能输出为 0342。
格式说明
输出时每行末尾的多余空格,不影响答案正确性。
样例输入
22222222222222222222
33333333333333333333
样例输出
55555555555555555555
思路
- 考虑到题目已经说是不超过200位的大整数,则宏定义N为200;
考虑到进位问题,故数组第一位不进行存放,因为可能两数相加会进1 - 主要思路:赋值,统计长度,对齐处理,进位,去除前导0
- [ 1 ] 赋值、统计长度:采用getchar()函数进行获取并赋给数组,规定遇\n退出,此时\n赋给了数组,但长度没有累计。同时,在长度到达201时跳出,题目规定是不超过200。
- [ 2 ]对齐处理:比较两个数组的长度,长度小者将数组进行移位,同时将原来的位置置0。
- [ 3 ]进位:将在长度内的数组元素相加,并追加(因为可能之前有进位)到数组C。
- [ 4 ]去除前导0:设置flag标志位,如果flag已经被赋予1,说明前导0已循环完毕,没有打印输出,可以安全打印出剩余的数组元素。
- [ 5 ]判断相加的数是否都为0:如果是0+0,则程序提前终止。用zero_if来统计所有的数组元素之和是否为0,如果都为0,说明是0+0。
下见代码
#include<stdio.h>
#define N 200
int main(){
int length_a=1,length_b=1,flag=0,zero_if=0;
char a[N+1]={0},b[N+1]={0},c[N+1]={0};//先初始化
int i,j;
//通过键盘输入的形式,每输入一个字符就计算长度,考虑到进位,从下标1开始赋值
//printf("请输入第一行:\n");
while((a[length_a]=getchar())!='\n'){//故在最后一位存放的是\n
a[length_a]-='0';
length_a++;
if(length_a>200){
break;
}
}
//在这里大家应注意的是:
//当遇\n退出循环时,\n赋给了数组,但是没有计入长度
//printf("请输入第二行:\n");
while((b[length_b]=getchar())!='\n'){//故在最后一位存放的是\n,但并没有计入
b[length_b]-='0';
length_b++;
if(length_b>200){
break;
}
}
if(length_a>length_b){//进行对齐处理
//printf("执行length_a>length_b");
for(i=length_b;i>=0;i--){//应该从后往前向后赋值
b[i+length_a-length_b]=b[i];
b[i]=0;
}
length_b=length_a;
}else if(length_a<length_b){
//printf("执行length_a<length_b");
for(i=length_a;i>=0;i--){
a[i+length_b-length_a]=a[i];
a[i]=0;
}
length_a=length_b;
}
//printf("对齐后处理\n");
for(i=length_a-1;i>=1;i--){
c[i]+=a[i]+b[i];
if(c[i]>=10){
c[i]%=10;//求余
c[i-1]+=1;//进位
}
}
for(i=0;i<length_a;i++){ //如果是0+0,即所有位数和是0,就输出0
zero_if+=c[i];
}
if(zero_if==0){
printf("0");
return 0;
}
//如果是0+0,则程序提前终止,不再执行以下程序
for(i=0;i<length_a;i++){
if(c[i]!=0){//测试例子,003003,去除前导0
flag=1;
}
if(flag){//如果flag已被赋予1,说明前导0已循环完毕,没有打印输出
printf("%d",c[i]);
}
}
return 0;
}