一个加法问题(大数相加)

b173980067 2008-08-29 02:28:56
Input:
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line consists of two positive integers, A and B. Notice that the integers are very large, that means you should not process them by using 32-bit integer. You may assume the length of each integer will not exceed 1000.
Output
For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line is the an equation "A + B = Sum", Sum means the result of A + B. Note there are some spaces int the equation. Output a blank line between two test cases.
输入:2(表示2组数据)
输入:
1 2
输出:
Case 1:
1 + 2 = 3
输入:
112233445566778899 998877665544332211
输出:
Case 2:
112233445566778899 + 998877665544332211 = 1111111111111111110

备注:是大数。





#include<stdio.h>
#include<string.h>
void main()
{
int i,t,flag,j,k,l,sum[1000];
char x1[1000],x2[1000];
scanf("%d",&t);
if(t<1||t>20)
return;
for(i=0;i<t;i++)
{
scanf("%s%s",x1,x2);
l=0;flag=0;
for(j=strlen(x1)-1,k=strlen(x2)-1;;j--,k--)
{
if(j==-1&&k<=-1||j<=-1&&k==-1)
break;
if(j>=0&&k<0)
x2[k]='0';
if(j<0&&k>=0)
x1[j]='0';
if(1==flag)
sum[l]=x1[j]+x2[k]+1-96;
else
sum[l]=x1[j]+x2[k]-96;
flag=0;
if(sum[l]>9)
flag=1;
sum[l]=sum[l]%10;
l++;
}
printf("Case %d:\n%s + %s = ",i+1,x1,x2);
if(flag==1)
printf("1");
for(j=l-1;j>=0;j--)
printf("%d",sum[j]);
printf("\n\n");
}
}


传上去通不过啊。晕了。。。
不知道哪里没有考虑到。高手指点。
...全文
764 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
_石头_ 2008-08-31
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 b173980067 的回复:]
你们好像没有帮我解决真正意义上的问题吧。。。
我是说为什么会A不过呢。我是做ACM的,条件要求很严格的。。。。
类似于有什么特殊问题没有考虑到这些的。。
向五楼的第一个问题我感觉有点道理的。。
但是同时字符串对齐又怎么解决了。。
请教~
[/Quote]
if(j>=0&&k <0)
x2[k]='0'; //这里数组越界了----写到了数组前面的空间了!
if(j <0&&k>=0)
x1[j]='0'; //同上。
其实楼主自己也可以这样测试一下:

if(j>=0&&k <0)
{
x2[k]='W';
printf("x2's address=%#x\n",x2); //输出数组的起始地址
printf("x2[%d]'s address=%#x\n",k,&x2[k]); //看是否存在越界
}
Kasmile 2008-08-31
  • 打赏
  • 举报
回复
哪大学的 ACM 呢?

_石头_ 2008-08-31
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 b173980067 的回复:]
....字符串对齐又怎么解决了。。
请教~
[/Quote]
用对齐字符串的方式写了一个,几个关于字符串的地方都作了一下注解,供lz参考:

#include <stdio.h>
#include <string.h>
#include <windows.h>
void main()
{
char x1[1000]={0},x2[1000]={0};
char *add=x1, *sum=x2, *result, *tmp, flag=0;
int len_add=0, len_sum=0, t,i=0;
printf("请输入运算次数(<20):");
scanf("%d",&t);
if(t <1 ||t>20)
return;
while(0<t--)
{
i=0; flag=0; fflush(stdin);
add=x1, sum=x2;
printf("请输入加数和被加数:\n");
scanf("%s%s",x1,x2);
if(strlen(x1)<strlen(x2)) //把最长的作为加数
{
add=x2;
sum=x1;
}
len_add=strlen(add);
len_sum=strlen(sum);
tmp=result=(char *)malloc(len_add+2); //多分配两个空间,即最高位进位和字符串的结尾
memset(result,'0',len_add-len_sum+1); //把被加数缺的前面几位用'0'补齐
strcpy(result+len_add-len_sum+1, sum); //把被加数的内容拷贝到后面几位中
add+=len_add-1;
result+=strlen(result)-1;
while(0<len_add--) //运算
{
*result+=*add+flag-'0';
flag=0;
if(*result>'9')
{
*result-=10;
flag=1;
}
result--;
add--;
}
*result+=flag; //最高位进位调整
while(*result=='0')
result++;
result=strlen(result)==0?result-1:result;
printf("\n%s\n+\n%s\n=\n%s\n",x1,x2,result);
free(tmp);
}
}

_石头_ 2008-08-31
  • 打赏
  • 举报
回复
这里还有一点瑕疵:
char x1[1000],x2[1000];//加数和被加数都允许1000位
sum[1001] //和就应该要多1位,否则可能产生溢出,因为最高位可能还有进位。
b173980067 2008-08-30
  • 打赏
  • 举报
回复
估计就上面的问题了。有高手能解答吗?
我刚又写了一个,这个传上去就通过了
#include<stdio.h>
#include<string.h>
void main()
{
int i,t,flag,j,k,index,sum[1000],temp;
char x1[1000],x2[1000];
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%s%s",x1,x2);
index=temp=flag=0;j=strlen(x1)-1;k=strlen(x2)-1;
while(j>=0&&k>=0)
{
temp=x1[j]+x2[k]-'0'-'0'+flag;
sum[index++]=temp%10;
flag=temp/10;
j--;k--;
}
if(j>=0)
{
while(j>=0)
{
temp = x1[j]-'0'+flag;
sum[index++]=temp%10;
flag= temp/10;
j--;
}
}
if(k>=0)
{
while(k>=0)
{
temp=x2[k]-'0'+flag;
sum[index++]=temp%10;
flag=temp/10;
k--;
}
}
printf("Case %d:\n%s + %s = ",i+1,x1,x2);
if(flag==1)
{
printf("1");
}
for(j=index-1;j>=0;j--)
printf("%d",sum[j]);
if(i==t-1)
printf("\n");
else
printf("\n\n");
}
}
b173980067 2008-08-29
  • 打赏
  • 举报
回复
你们好像没有帮我解决真正意义上的问题吧。。。
我是说为什么会A不过呢。我是做ACM的,条件要求很严格的。。。。
类似于有什么特殊问题没有考虑到这些的。。
向五楼的第一个问题我感觉有点道理的。。
但是同时字符串对齐又怎么解决了。。
请教~
b173980067 2008-08-29
  • 打赏
  • 举报
回复
今天去学车了。。哈哈。。。叫我夜猫子啊。。。明天就要去学校了。野猫不成了
lunarfan 2008-08-29
  • 打赏
  • 举报
回复
变量命名太糟糕
古董啊 2008-08-29
  • 打赏
  • 举报
回复
受教
tangshuiling 2008-08-29
  • 打赏
  • 举报
回复
楼主参考这个,很好懂,不过没考虑负数的情况:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string num1("3254387423432253424432");
string num2("125489982374892345");

int len=(num1.length()>num2.length()? num1.length():num2.length())+1;
string num1temp=string((len-num1.length()),'0')+num1;
string num2temp=string((len-num2.length()),'0')+num2;
string s(len,'0');
int i=len;
for(int carry=0;i>0;i--,carry/=10)
{
carry+=num1temp[i]-'0'+num2temp[i]-'0';
s[i]=char(carry%10+'0');
}
cout<<s.substr(s.find_first_not_of('0'));
system("pause");
return 0;
}


brookmill 2008-08-29
  • 打赏
  • 举报
回复
有几个问题和LZ还有1楼的夜猫子探讨 :)
1.
if(j>=0&&k <0)
x2[k]='0';
if(j <0&&k>=0)
x1[j]='0';
这段的意思我大致明白,是把较短的字符串前面补0。
可是k<0的时候,x2[k]会不会有问题?
根据我以前的理解,x2[k]等同于*(x2+k)。这样,如果k<0,就会越界访问到x2之前的内存?

2.
在正式的项目里,对于用户的输入,一定要检查,判断是否都在'0'和'9'之间。用户是很不可靠的,不知道他们会给输入些什么样稀奇古怪的东东。

3.
if(1==flag)
sum[l]=x1[j]+x2[k]+1-96;
else
sum[l]=x1[j]+x2[k]-96;
改写成这样可能更好
sum[l] = x1[j] - '0' + x2[k] - '0' + flag;

4.
我用gcc编译的时候,这行给了个warning
if(j==-1&&k <=-1 ||j <=-1&&k==-1)
warning: suggest parentheses around && within ||
还是加上括号的好,要不看着眼晕
_石头_ 2008-08-29
  • 打赏
  • 举报
回复
没发现问题,运行了一下结果也正常啊!顺便吧代码格式调整了一下!

#include <stdio.h>
#include <string.h>
void main()
{
int i,t,flag,j,k,l,sum[1000];
char x1[1000],x2[1000];
scanf("%d",&t);
if(t <1 ||t>20)
return;
for(i=0;i <t;i++)
{
scanf("%s%s",x1,x2);
l=0;flag=0;
for(j=strlen(x1)-1,k=strlen(x2)-1;;j--,k--)
{
if(j==-1&&k <=-1 ||j <=-1&&k==-1)
break;
if(j>=0&&k <0)
x2[k]='0';
if(j <0&&k>=0)
x1[j]='0';
if(1==flag)
sum[l]=x1[j]+x2[k]+1-96;
else
sum[l]=x1[j]+x2[k]-96;
flag=0;
if(sum[l]>9)
flag=1;
sum[l]=sum[l]%10;
l++;
}
printf("Case %d:\n%s + %s = ",i+1,x1,x2);
if(flag==1)
printf("1");
for(j=l-1;j>=0;j--)
printf("%d",sum[j]);
printf("\n\n");
}
}
_石头_ 2008-08-29
  • 打赏
  • 举报
回复
嗬嗬!楼上也是夜猫子啊!
brookmill 2008-08-29
  • 打赏
  • 举报
回复
if(t <1 ¦ ¦t>20) //////////////////////////////
return;
for(i=0;i <t;i++)
{
scanf("%s%s",x1,x2);
l=0;flag=0;
for(j=strlen(x1)-1,k=strlen(x2)-1;;j--,k--)
{
if(j==-1&&k <=-1 ¦ ¦j <=-1&&k==-1) ///////////////////

有|的两行出错,不知道是中文编码还是别的原因。
把原来的 ¦ ¦ 删掉手工改成||就好了,代码本身好像没问题。
LZ用什么“传上去”?
太乙 2008-08-29
  • 打赏
  • 举报
回复
有没有兴趣看看这个呢?
http://download.csdn.net/source/403510
大数的加减乘除~包括正负数,余数的处理!
_石头_ 2008-08-29
  • 打赏
  • 举报
回复
第一个问题:
可以用尝试字符串对其的方法来解决

第二个问题:
建议将scanf("%s%s",x1,x2);
改为:scanf("%[0-9]%[0-9]",x1,x2); 在输入的时候遇到非数字字符就自动截断,避免非法字符参与运算。
第三个问题:
改写成这样更精炼些:
sum[l] = x1[j] - '0' + x2[k] - '0' + flag;
其实我觉得没必要减去两个'0',完全可以直接用字符运算,把后面的if改为如下形式:
if(sum[l]>'9')
{
flag=1;
sum[l]-='9'; //这样比%运算的效率也高些。
}
最后面直接用%c格式输出就行了
_石头_ 2008-08-29
  • 打赏
  • 举报
回复
if(t <1 ¦ ¦t>20)
if(j==-1&&k <=-1 ¦ ¦j <=-1&&k==-1)
这好像是乱码啊!

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧