這是一個經典的上機題目,要求輸入兩個數字字符串,實現任何長度的加法,供上機筆試的同學參考
/*
Name:
Copyright:
Author:
Date:
Description: 高精度加法
*/
#include <iostream>
using namespace std;
//這裏爲最大位數 的長度
#define N 100
void swap(char *s , int p ,int r)
{
char tem;
int i,j;
for(i=p,j=r;i<j;i++,j--)
{
tem=s[i];
s[i] = s[j];
s[j] = tem;
}
}
void jtoAdd(char *s1, char *s2,char *ret)
//都爲正
{
int i,j,k;
int s1len=strlen(s1);
int s2len=strlen(s2);
int t;
int tem=0;
for(k=0,i=s1len-1,j=s2len-1;i>=0&&j>=0;i--,j--,k++)
{
t=s1[i]-'0'+s2[j]-'0'+tem;
ret[k]=t%10+'0';//轉化爲字符串
tem=t/10;//表示進位
}
if(s1len==s2len)
{
if(tem)
{
ret[k]=tem + '0' ;
swap(ret,0,k);
}
else
{
swap(ret,0,k-1);
}
return ;
}
if(s1len>s2len)
{
for(;i>=0;i--,k++)
{
t=s1[i]-'0'+tem;
ret[k]=t%10+'0';
tem=t/10;
}
}
else
{
for(;j>=0;j--,k++)
{
t=s2[j]-'0'+tem;
ret[k]=t%10+'0';
tem=t/10;
}
}
if(tem==0)
{
swap(ret,0,k-1);
}
else
{
ret[k]=tem+'0';
swap(ret,0,k);
}
}
void jToSub(char *s1, char *s2,char *ret)
{//前面已經保證 計算的結果爲正數
int i,j,k;
int len1=strlen(s1);
int len2=strlen(s2);
//最開始沒有借位
bool jw=0;
for(k=0,i=len1-1,j=len2-1 ;i>=0 && j>=0; i--,j--,k++)
{
if(jw)
s1[i]-=1;
if(s1[i] - s2[j]<0)
{
jw = 1;
s1[i]+=10;
}
else
jw = 0;
ret[k] = s1[i] - s2[j] +'0';
}
if(len1>len2)
{
for(;i>=0 ;i--, k++)
{
if(jw)
s1[i]-=1;
if(s1[i] < '0')
{
jw = 1;
s1[i]+=10;
}
else
jw = 0;
ret[k] = s1[i]; // 這裏沒有 + '0'
}
}
for(i=len1 -1 ;i>=0;i--)
{
if(ret[i] == '0')
{
ret[i] = '\0';
}
else
break;
}
swap(ret,0,i);
}
///////////////////////////////////////////////////
void AddByStr(char *s1, char *s2,char *ret)
{
int i ,j;
if(s1[0]!='-'&&s2[0]!='-')
{
jtoAdd(s1,s2,ret);
return ;
}
if(s1[0]=='-'&&s2[0]=='-')
{
ret[0]='-';
jtoAdd(s1+1,s2+1,ret+1);
return ;
}
//一正一負
//假定2是正的
int sz=2;
i=1;
j=0;
if('-' != s1[0])
{
i=0;
j=1;
sz=1;
}
int cmp;
int cdc = strlen(s1+i) - strlen(s2+j);
if(cdc == 0)
{
cmp = strcmp(s1+i,s2+j);
if(!cmp)
{
ret[0] = '0';
return;
}
if(sz==1 && cmp>0 )
//最後結果爲正
{
jToSub(s1+i, s2+j, ret);
return ;
}
if(sz ==1 && cmp<0)
{
ret[0] = '-';
jToSub(s2+j,s1+i, ret+1);
return ;
}
if(sz == 2 && cmp<0)
{
jToSub(s2+j,s1+i, ret);
return ;
}
if(sz == 2 && cmp>0)
{
ret[0] = '-';
jToSub(s1+i, s2+j, ret+1);
return ;
}
}
else
{
if(1 == sz && cdc > 0 )
{
jToSub(s1+i, s2+j, ret);
return;
}
if(1 == sz && cdc<0 )
{
ret[0] = '-';
jToSub(s2+j,s1+i, ret+1);
return ;
}
if(2 == sz && strlen(s1+i) < strlen(s2+j) )
{
jToSub(s2+j,s1+i, ret);
return ;
}
if(2 == sz && strlen(s1+i) > strlen(s2+j) )
{
ret[0] = '-';
jToSub(s1+i, s2+j, ret+1);
return ;
}
}
}
///////////////////////////////////////
//這個函數用於判斷輸入是否合法,如果合法則將字串整形
bool LargeAdd(char *s1, char *s2,char *ret)
{
int i,j;
int len1, len2;
bool s10=0,s20=0;
for(i=0;i<N+2;i++)
ret[i]= 0;
//這個函數判斷輸入是否合法
if('-'==s1[0] || s1[0]>='0' && s1[0]<='9')
{
len1=strlen(s1);
for(i=1;i<len1;i++)
{
if(s1[i]>='0' && s1[i]<='9')
{}
else
return false;//輸入不合法
}
//執行到這裏,輸入合法
//去掉多餘的0
i=0;
if('-' == s1[0])
i=1;
for(j=i;j<len1;j++)
{
if('0'!=s1[j])
break;
}
if(j == len1)
s10=1;//說明爲全零串
if(!s10 && i!=j)
{
for(;j<len1;i++,j++)
{
s1[i]=s1[j];
}
for(;i<len1;i++)
{
s1[i]=0;
}
}
}
else
{
return false;
}
if('-'==s2[0] || s2[0]>='0' && s2[0]<='9')
{
len2=strlen(s2);
for(i=1;i<len2;i++)
{
if(s2[i]>='0' && s2[i]<='9')
{}
else
return false;//輸入不合法
}
//去掉多餘的0
i=0;
if('-' ==s2[0])
i=1;
for(j=i;j<len2;j++)
{
if('0'!=s2[j])
break;
}
if(j == len2)
s20=1;//說明爲全零串
if(!s20 && i!=j)
{
for(;j<len2;i++,j++)
{
s2[i]=s2[j];
}
for(;i<len2;i++)
{
s2[i]='\0';
}
}
}
else
{
return false;
}
if(s10 && s20)
{
ret[0] = '0';
return true;
}
if(s10)
{
strcpy(ret,s2);
return 1;
}
if(s20)
{
strcpy(ret,s1);
return 1;
}
AddByStr(s1,s2,ret);
return true;
}
int main()
{
char s1[N+1];
char s2[N+1];//="-0000010000000000000000";
printf("輸入相加的兩個數:\n");
gets(s1);
gets(s2);
char ret[N+2];
bool b;
b= LargeAdd(s1,s2,ret);
if(!b)
printf("輸入不合法");
else
printf(" = %s", ret);
printf("\n");
system("PAUSE");
}
分析,首先宏定義N標示最大的輸入位數,包含前面的負號。如果是正數,不需要加+符號。代碼是最好的註釋,更改N的值,可以支持任意位數的整數相加。