【题目来源】:https://www.51nod.com
【题意】
大数加法模拟,包含负数。
【思路】
直接就是模拟,模拟出加,减法就可以了。还行。
【代码】
//这是我第一次规范代码,利于看懂
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char string_NumOne[10000+10];
char string_NumTwo[10000+10];
int array_NumOne[10000+10];
int array_NumTwo[10000+10];
int array_add[10000+10];
int array_ninus[10000+10];
void ninus_cal_len_diff(int str_NumOne[],int lenOne,int str_NumTwo[],int lenTwo,bool flag)
{
for(int i=0; i<lenOne; i++)
{
int tmp=str_NumOne[i]-str_NumTwo[i];
if(tmp<0)
{
int j=i;
while(1)
{
j++;
if(str_NumOne[j]!=0)
{
str_NumOne[j]--;
for(int k=i+1; k<j; k++)
str_NumOne[k]=9;
array_ninus[i]=10+tmp;
break;
}
}
}
else array_ninus[i]=tmp;
}
if(flag) printf("-");
if(array_ninus[lenOne-1]!=0) printf("%d",array_ninus[lenOne-1]);
if(array_ninus[lenOne-1]==0)
{
while(!array_ninus[lenOne-2])
{
--lenOne;
}
}
for(int i=lenOne-2; i>=0; i--) printf("%d",array_ninus[i]);
printf("\n");
}
void minus_bigNum(int str_NumOne[],int lenOne,int str_NumTwo[],int lenTwo)
{
if(lenOne<lenTwo)
{
ninus_cal_len_diff(str_NumTwo,lenTwo,str_NumOne,lenOne,1);
}
else if(lenOne>lenTwo)
{
ninus_cal_len_diff(str_NumOne,lenOne,str_NumTwo,lenTwo,0);
}
else
{
bool flag=0;
for(int i=lenOne-1; i>=0; i--)
{
if(str_NumOne[i]<str_NumTwo[i])
{
flag=1;
break;
}
else if(str_NumOne[i]>str_NumTwo[i])
break;
}
if(!flag) ninus_cal_len_diff(str_NumOne,lenOne,str_NumTwo,lenTwo,0);
else ninus_cal_len_diff(str_NumTwo,lenTwo,str_NumOne,lenOne,1);
}
}
int main()
{
scanf("%s",string_NumOne);
scanf("%s",string_NumTwo);
bool vis_signOne=0,vis_signTwo=0;
if(string_NumOne[0]=='-') vis_signOne=1;
if(string_NumTwo[0]=='-') vis_signTwo=1;
int lenOne=strlen(string_NumOne);
int lenTwo=strlen(string_NumTwo);
int frOne=0,frTwo=0;
if(vis_signOne) frOne=1;
if(vis_signTwo) frTwo=1;
for(int i=lenOne-1; i>=frOne; i--)
array_NumOne[lenOne-i-1]=string_NumOne[i]-'0';
for(int i=lenTwo-1; i>=frTwo; i--)
array_NumTwo[lenTwo-i-1]=string_NumTwo[i]-'0';
lenOne-=frOne;
lenTwo-=frTwo;
if((vis_signOne&&vis_signTwo)||(!vis_signOne&&!vis_signTwo))
{
int lenMax=max(lenOne,lenTwo);
int carry=0;
for(int i=0; i<=lenMax; i++)
{
int tmp=array_NumOne[i]+array_NumTwo[i]+carry;
carry=0;
if(tmp>9) carry++;
array_add[i]=tmp%10;
}
if(vis_signOne) printf("-");
if(array_add[lenMax]!=0) printf("%d",array_add[lenMax]);
for(int i=lenMax-1; i>=0; i--) printf("%d",array_add[i]);
printf("\n");
}
else
{
if(vis_signOne) minus_bigNum(array_NumTwo,lenTwo,array_NumOne,lenOne);
else minus_bigNum(array_NumOne,lenOne,array_NumTwo,lenTwo);
}
}
附上小伙伴有意思的思路以及代码(超简洁):
不用写出减法,直接加法就好了,如果数是负数,那么就把数组里所有数字都变成负的,相加就好,最后判断首位是否为负,若是负,那么说明这个值就是负的。
【代码】
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<cmath>
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]=='-')//如果aa是负数,就把除了负号之外的数字全部变为负数。
{
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;//r和c[i]正负不定
c[i]=p%10;
}
if(r) c[lc++]=r;
while(lc>1&&c[lc-1]==0) lc--;//去除前导0,至少留一位
int flag=1;
//用最高位(c[lc-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");
}
//全程口述。。