最近遇到一个关于大数的问题顿时感觉好方,决定系统学一下大数。
注意:关于大数问题,由于数组不好界定输入数的大小(数组的长度),因此主要思想就是先用字符串输入保存在字符串数组中,再逆序存入整形数组进行最后逐位运算。
刚开始通过博客http://www.cnblogs.com/Stone-sqrt3/archive/2013/04/25/3042338.html写的代码:
思路:输入采用字符数组保存,然后将输入存在整形数组里,然后逐位相加即可,同时注意进位处理。
//大数加法1
#include<stdio.h>
#include<string.h>
#define M 10000
#define kk -48// 0字符的ASC II值是48
/*取lengA和lengB大的那个 */
int maxl(int a,int b)
{
return a>b?a:b;
}
/*化字符为数字 */
int zz(char c)
{
return c-'0';
}
int main()
{
char a[M],b[M];
int A,B,Maxl,c,hh,sum[M],i,an,bn;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
while(~scanf("%s%s",&a,&b))
{
A=strlen(a);
B=strlen(b);
printf("A=%d B=%d\n",A,B);
/*把A和B字符串的顺序逆序排列 */
for(i=0;i<(A+1)/2;i++)
{
if(i==A-1-i) break;// 排除共奇数位个大数的影响
a[i]+=a[A-1-i];
a[A-1-i]=a[i]-a[A-1-i];
a[i]-=a[A-1-i];
}
for(i=0;i<(B+1)/2;i++)
{
if(i==B-1-i) break;// 排除共奇数位个大数的影响
b[i]+=b[B-1-i];
b[B-1-i]=b[i]-b[B-1-i];
b[i]-=b[B-1-i];
}
/*加运算 */
Maxl=maxl(A,B);
for(i=0,c=0;i<=Maxl;i++)
{
an=zz(a[i]);
bn=zz(b[i]);
if(an==kk) an=0;// 排除初始化中0字符的影响;
if(bn==kk) bn=0;// 排除初始化中0字符的影响;
hh=an+bn+c;
sum[i]=hh%10;
c=hh/10;
}
/*最后一位若大于0就先输出*/
if(sum[Maxl]>0) printf("%d",sum[Maxl]);
/*逆序打印sum[] */
for(i=Maxl-1;i>=0;i--)
{
printf("%d",sum[i]);
}
printf("\n");
}
return 0;
}
虽然代码运行符合要求,但感觉比较麻烦,因此又写了下面这个代码:
//大数加法2
#include<stdio.h>
#include<string.h>
#define M 100005
char s1[M],s2[M];
int a[M],b[M],c[M];
int main()
{
int i,j,k,n,m;
while(scanf("%s%s",s1,s2))
{
memset(c,0,sizeof(c));
n=strlen(s1);
m=strlen(s2);
printf("s1的长度= %d s2的长度= %d\n",n,m);
/* 把字符串s1和s2逆序用数字排列*/
for(i=0; i<n; i++)
a[i]=s1[n-i-1]-'0';
for(i=0; i<m; i++)
b[i]=s2[m-i-1]-'0';
/*加运算*/
if(n>m) k=n;
else k=m;
for(i=0; i<=k; i++)
{
c[i]+=a[i]+b[i];
if(c[i]>9)
{
c[i+1]++;
c[i]%=10;
}
}
/*去除前导0*/
i=k;
while(c[i]==0) i--;
/*判断两个非负数之和是否为0,以及逆序打印c[]*/
if(i<0) printf("0");
else
{
for(; i>=0; i--)
printf("%d",c[i]);
}
printf("\n");
}
return 0;
}