51nod1005---大数加法(51nod基础:加减模拟)

【题目来源】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");
}
//全程口述。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值