OJ地址:https://vjudge.net/problem/OpenJ_Bailian-2981
求两个不超过200位的非负整数的和。
Input
有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。
Output
一行,即相加后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。
Sample Input
22222222222222222222
33333333333333333333
Sample Output
55555555555555555555
思路:
大整数参考链接:大整数
大整数四则运算:大整数的四则运算
程序代码:
错误:原因未知;
//定义一个结构体存储大整数
struct bign {
int d[201];
int len;
//初始化结构体
bign() {
memset(d,0,sizeof(d));
len = 0;
}
};
//将整数转换为bign
bign change(char str[]) {
bign a;
a.len = strlen(str);
for(int i=0;i<a.len;i++) {
a.d[i] = str[a.len-i-1]-'0';
}
return a;
}
//高精度加法
bign add(bign a,bign b) {
bign c;
int carry = 0; //carry是进位
for(int i=0;i<a.len||i<b.len;i++) { //以较长的为界限
int temp = a.d[i]+b.d[i]+carry; //两个对应位与进位相加
c.d[c.len++] = temp%10; //个位数为该位的结果
carry = temp/10; //十位数为新的进位
}
//两个数都已经结束但依然存在进位
if(carry != 0) {
c.d[c.len++] = carry; //则直接赋给结果的最高位
}
return c;
}
//输出bign
void print(bign a) {
int flag=0;
for(int i=a.len-1;i>=0;i--) {
if(flag==0&&a.d[i]==0){
continue;
}else{
printf("%d",a.d[i]);
flag=1;
}
}
}
int main(){
char str1[201],str2[201];
scanf("%s%s",str1,str2);
bign a = change(str1);
bign b = change(str2);
print(add(a,b));
printf("\n");
return 0;
}
正确:
/* Bailian2981 大整数加法 */
char a[N+1], b[N+1];
char ans[N+1];
int main(void)
{
int anslen, carry, len, i, j;
scanf("%s", a);
scanf("%s", b);
memset(ans, 0, sizeof(ans));
anslen = len = strlen(a);
for(i=len-1, j=0; i>=0; i--)
ans[j++] = a[i] - '0';
len = strlen(b);
if(len > anslen)
anslen = len;
carry = 0;
for(i=len-1, j=0; i>=0; i--,j++) {
ans[j] += b[i] - '0' + carry;
carry = ans[j] / BASE;
ans[j] %= BASE;
}
while(carry > 0) {
ans[j] += carry;
carry = ans[j] / BASE;
ans[j++] %= BASE;
}
if(j > anslen)
anslen = j;
/* 去除前导的多个0 */
for(i=anslen-1; i>=0; i--)
if(ans[i])
break;
if(i < 0)
i = 0;
/* 输出结果 */
for(; i>=0; i--)
printf("%d", ans[i]);
printf("\n");
return 0;
}
参考于:javascript:void(0)
运行结果: