原题:
Problem Description
I have a very simple problem for you. Given two integersA and B, your job is to calculate the Sum of A + B.
Input
The first line of the input contains an integerT(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 integersare 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. Thefirst line is "Case #:", # means the number of the test case. Thesecond line is the an equation "A + B = Sum", Sum means the result ofA + B. Note there are some spaces int the equation. Output a blank line betweentwo test cases.
2
1 2
112233445566778899 998877665544332211
注意下面的输出格式要求:(说实话,你们老师要求这样写吗? )
Case 1:
1 + 2 = 3
Case 2:
112233445566778899 + 998877665544332211 =1111111111111111110
两行之间有空行,最后一行无空行,这个很简单,一个if或者for就可以解决。
下面进行分析。先声明,我只分析我认为的重点,并尽最大能力让跟我同水平及以下的朋友有所收获。至于你是否有更高的见解,欢迎你将它无偿的发表在下面面的留言板上。
分析:
首先这是一个加法问题。
其次,此题涉及到多组数据输入。
再次,本题明确说明这是一道大数据的题。
如果是简单的加法问题,我们可以这样:
#include<stdio.h>
int main ()
{
int a,b;
while(scanf("%d %d",&a,&b)!=EOF)
printf("a+b=%d",a+b);
return 0;
}
但是对于输入的数或者运算所得数超过了我们可以定义的数据类型,再用这种方法,就会出现一系列的错误。
度娘告诉你,这一类的问题有一个高大上的名字,叫做“高精度运算”。她还告诉你,遇到这种情况,你可以利用的数据类型有两种,一种是字符串,另一种是数组。http://baike.baidu.com/link?url=CpO17lLZr75a-a47YPC05dp7nfmeAQWEMimnTjDZ1oKmLZBfBFUDFscxRUz_nfSa
根据度娘的提示,我决定就采取她说的方法:用字符串读入数据,用数组存储数据。
这个又涉及到字符型和整型之间的转换,这一点在下面的代码中将有相应解释,看的时候注意点就是。
回想在你小学的时候,你学过一种东西叫做“竖式”,它的基本原理是:个位与个位对齐,十位与十位对齐,……;对齐的个位的上面加下面,如果得出的数超过十,就把超出的部分进给十位,没超出的留在原位上。在编程中,通过“/”和“%”的运算来实现。“/”得到进位的数,“%”得到留下的数。
本题的思路就是,利用数组的每个元素,储存大数据的各个位上的数。各个位上的数由上面的算法得到。
代码如下:
#include<stdio.h>
#include<string.h>
int main()
{
chara[10001],b[10001];//将大数据分解成字符,作为一个数组输入
int a1[10001]={0},b1[10001]={0};//s[]作为两个大数据运算后的和,a1[],b1[]分别保存大数据转换为数字型后的各位数
int lena,lenb;//大数据的长度
int i,j,t;
int m;//与n搭配的计数单位
int n;//代表测试数据组数
int x;//代表Case :x
scanf("%d",&n);//输入测试组数
x=1;//为输出Case :x做准备
for(m=0;m<n;m++)//从第一组数据开始,每一组进行处理
{
int s[20002] ={0},k=0;//注意它们的位置
scanf("%s%s",a,b);//输入两个大数
printf("Case%d:\n", x);
printf("%s + %s = ", a, b);
lena=strlen(a);
lenb=strlen(b);//测量它们的长度
for(i=0;i<lena;i++)
a1[i]=a[i]-48;
for(j=0;j<lenb;j++)
b1[j]=b[j]-48;//0的ASCII码是48,这样做是把字符型转换为数字型,或者可以:b1[ ]=b1[ ]-'0';
while(i>=0&&j>=0)//倒着处理,最低位开始
{
s[k]=a1[i]+b1[j];//对位相加,先不进位
k++;
i--;
j--;
}
//对不齐的那些位,s[]等于a1[],b1[]中大于等于0的
if(i>=0)
while(i>=0)
{
s[k]=a1[i];
k++;
i--;
}
else if(j>=0)
while(j>=0)
{
s[k]=b1[j];
k++;
j--;
}
for(t=1;t<k;t++)//从个位到倒数第二最高位,进行进位处理
if(s[t]>=10)
{
s[t]%=10;
s[t+1]++;
}
if(s[k]!=0)//最高位如果不为零,就直接输出
printf("%d",s[k]);
for(t=k-1;t>0;t--)//从倒数第二高位起,开始输出。因为s[ ]是从个位开始加的,所以输出的时候,在形式上是逆序输出的。
printf("%d",s[t]);
printf("%c",'\n');//输完之后再加回车
if(x!=n)printf("%c ",'\n'); //注意格式,非最后一组数据,后面有空行。
x++;
}
return0;
}
我的错误:
1.出现几组加和累加的现象。
2.Case x:这里的x显示异常。
出错原因:
1.由于是多组数据输入,需要刷新的数据初始化的位置放错,一组测试数据运算完之后,没有得到刷新,导致累加。
2.倒数第五行的if(x!=n)粗心写成if(x=!n),没有及时检查出来。
总结:
多组数据输入的,对于需要刷新的数据,应该放在每一次的循环内部开始部分。
此种解法是先进行对位相加,然后再进行进位处理,这样做清晰明了,易于理解。下面是把两个工作同时做到。由于分离各个位上的数的操作,得到的是逆序的数字,意思就是54321这个数分离后是1 2 3 4 5,所以我采用的方式是在开始,就把a[],b[]各个字符转化为整型,逆序存入a1[],b1[]中。最后还是逆序输出s[i]。
#include <stdio.h>
#include<string.h>
int main()
{
chara[1001], b[1001];
intn, i, lena, lenb, len_max, x = 1, k;
scanf("%d",&n);
getchar();
while(n--)//对应下面对输出格式的限定(if(n >= 1) printf("\n");)
{
inta1[10001] = {0}, b1[10001] = {0}, s[20002] = {0};
scanf("%s",a);
lena= strlen(a);
//转为数字,逆序保存
for(i= 0; i <lena;i++)
a1[i]= a[lena - 1 - i] - '0';
scanf("%s",b);
lenb= strlen(b);
for(i= 0; i <lenb;i++)
b1[i]= b[lenb - 1 - i] - '0';
if(lena> lenb)
len_max= lena;
else
len_max= lenb;
k= 0;
//变加边实现进位(关键看这里)
for(i= 0; i <len_max ;i++)
{
s[i]= (a1[i] + b1[i] + k) % 10;
k= (a1[i] + b1[i] + k) / 10;
}
//最高位的进位情况
if(k!= 0) s[len_max] = 1;
printf("Case%d:\n", x);
x++;
printf("%s+ %s = ", a, b);
if(s[len_max]== 1)
printf("1");
for(i= len_max - 1; i >= 0;i--)//逆序输出
{
printf("%d",s[i]);
}
printf("\n");
if(n>= 1) printf("\n");
}
return0;
}
完。
请指教!
期待你的鼓励哦!