对于大数加法,我看到了三种类型题:
一种是正整数的加法,一种是正数加法(正数可以是小数),还有一种整数(整数可以是负数)加法,下面分析下这三种的做法。
正整数加法:http://acm.hdu.edu.cn/showproblem.php?pid=1002(题目链接)
代码如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char aa[10010],bb[10010];//以字符串的形式输入
int a[10010],b[10010],c[10010];
int main()
{
int t,k=1;
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
scanf("%s%s",aa,bb);
int la=strlen(aa);
int lb=strlen(bb);
int j=0;
for(int i=la-1; i>=0; i--)//倒着存到数组a中
a[j++]=aa[i]-'0';
j=0;
for(int i=lb-1; i>=0; i--)//倒着存到数组b中
b[j++]=bb[i]-'0';
int lc=max(la,lb),p=0,r=0;看看两个字符串那个长,当做数组c的长度
for(int i=0; i<lc; i++)
{
p=a[i]+b[i]+r;
r=p/10;
c[i]=p%10;
}
if(r)
c[lc++]++;//如果两个数相加需要往前进一位,让数组c长度变长,把进位存入
while(lc>1&&c[lc-1]==0)//如果相加前面有0,则去掉,在这道题中这种情况不会出现,下面就有可能出现
lc--;
printf("Case %d:\n",k++);
printf("%s + ",aa);
printf("%s = ",bb);
for(int i=lc-1; i>=0; i--)
printf("%d",c[i]);
printf("\n");
if(t)
printf("\n");
}
}
正数加法:http://acm.hdu.edu.cn/showproblem.php?pid=1753
这道题和上面的方法差不多。只是把小数部分和整数部分分开算,然后组装起来就好
代码如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char aa[410],bb[410];
int a[410],b[410],c[410],d[410];
int s1[410],s2[410];
int main()
{
while(~scanf("%s%s",aa,bb))
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
int laa=strlen(aa),lbb=strlen(bb);
int k=0,l=0,la=laa,lb=lbb,i,j;
for(i=0; i<la; i++)
{
if(aa[i]=='.')
{
k=i;
break;
}
}
for(i=0; i<lb; i++)
{
if(bb[i]=='.')
{
l=i;
break;
}
}
if(k!=0)la=k;
if(l!=0)lb=i;
for(i=la-1,j=0; i>=0; i--)
a[j++]=aa[i]-'0';
for(i=la+1,j=0; i<laa; i++)
b[j++]=aa[i]-'0';
for(i=lb-1,j=0; i>=0; i--)
c[j++]=bb[i]-'0';
for(i=lb+1,j=0; i<lbb; i++)
d[j++]=bb[i]-'0';
int r=0,q;
l=max(laa-la,lbb-lb);
for(int i=l; i>=0; i--)
{
q=b[i]+d[i]+r;
r=q/10;
s2[i]=q%10;
}
k=max(la,lb);
for(i=0; i<k; i++)
{
q=a[i]+c[i]+r;
r=q/10;
s1[i]=q%10;
}
if(r)
s1[k++]=r;
q=l;
for(int i=q-1;i>=0;i--)
{
if(s2[i]==0)
l--;
else
break;
}
for(i=k-1; i>=0; i--)
printf("%d",s1[i]);
if(l!=0)
{
printf(".");
for(i=0; i<l; i++)
printf("%d",s2[i]);
}
printf("\n");
}
}
整数加法(可以是负数):https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1005
这道题和上面的做法有些不同,这道题是把负数的每一位变为负数和另一个数相加减,然后再每一位加10或是减10.
代码如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
char aa[10005],bb[10005];
int a[10005],b[10005];
int c[10005];
int main()
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
scanf("%s%s",aa,bb);
int la=strlen(aa);
int lb=strlen(bb);
for(int i=la-1,j=0;i>0;i--)
a[j++]=aa[i]-'0';
if(aa[0]=='-')
{
la--;
for(int i=0;i<la;i++)
a[i]=-a[i];
}
else
a[la-1]=aa[0]-'0';
for(int i=lb-1,j=0;i>0;i--)
b[j++]=bb[i]-'0';
if(bb[0]=='-')
{
lb--;
for(int i=0;i<lb;i++)
b[i]=-b[i];
}
else
b[lb-1]=bb[0]-'0';
int lc=max(la,lb);
int p,r=0;
for(int i=0;i<lc;i++)
{
p=a[i]+b[i]+r;
r=p/10;
c[i]=p%10;
}
if(r)
c[lc++]=r;
while(lc>1&&c[lc-1]==0)
lc--;
int flag=1;
if(c[lc-1]>=0)
{
for(int i=0;i<lc;i++)
{
while(c[i]<0)
{
c[i+1]--;
c[i]+=10;
}
}
}
if(c[lc-1]<0)
{
flag=-1;
for(int i=0;i<lc;i++)
{
while(c[i]>0)
{
c[i+1]++;
c[i]-=10;
}
}
}
if(flag<0)
printf("-");
while(lc>1&&c[lc-1]==0)
lc--;
for(int i=lc-1;i>=0;i--)
printf("%d",abs(c[i]));
printf("\n");
}