• 51Nod-1005 大数加法


    如题
    这里写图片描述

    这是一道很简单的基础题,当年大一的时候在自己学校的oj上做过这道题的简单版,不过没做出来,现在转眼好几年了,算法一直不好,于是重新来练练手。

    这道题用java或者python等语言可以用很短的代码写出来,但那没意义了,所以我用的是c++。
    思路很简单,无非用字符型数组保存即可。
    但是这道题因为有负数,所以负数必须分类讨论。
    如果两个都是负数,好办,直接输出一个负号,然后按正数加法对数字进行运算即可。
    如果一个正数一个负数,就需要额外设计一个减法了。
    然后长度的话,虽然做题的时候数组空间的申请都讲究要比它说的大一点,但我一开始想着既然范围是不超过10000,申请10000不就够了么,果然天真的我就错了,没考虑进位,居然还出现了RTE,哎呀呀。
    中间还出现了一个问题,因为要循环输入嘛,里面循环调用的非main函数里面的局部变量的值每次都是一样的,注意是局部变量,写java写惯了的我觉得很奇怪,相关细节请参看我的另一篇博客:由c++循环中局部变量地址不变而引发的思考

    下面放上我冗长的代码(一些边边角角能省的都省了/笑)

    #include<bits/stdc++.h>
    using namespace std;
    
    void doCut(char *a,char *b)
    {
        //cout<<endl<<"a="<<a<<"  b="<<b<<endl;
        int jie=0;
        int alen=strlen(a)-1;
        int blen=strlen(b)-1;
        int c[10005]={''};
        int a1=0,b1=0,c1=0;
    
        while(alen>=0 && blen>=0)
        {
            c[c1] = a[alen]-b[blen]-jie;
            if(c[c1] < 0)
            {
                jie=1;
                c[c1] +=10;
            }
            else
            {
                jie=0;
            }
            c1++;
            alen--;
            blen--;
        }
        while(alen>=0)
        {
            c[c1] = a[alen]-'0'-jie;
            if(c[c1] < 0)
            {
                jie=1;
                c[c1]+=10;
            }
            else{
                jie=0;
            }
    
            c1++;
            alen--;
        }
        int d=0;
        for(int i=c1--;i>=0;i--)
        {
            if(d == 0)
            {
                if(c[i] == 0) continue;
                d=1;
            }
            cout<<c[i];
        }
        cout<<endl;
    
    }
    
    void dothat(char *a,char *b)
    {
        int alen = strlen(a) -1;
        int blen = strlen(b) -1;
    
        int a1=0,b1=0;
    
    
        if(alen > blen)
        {
            cout<<"-";
            doCut(a,b);
            return;
        }
        if(alen < blen)
        {
            doCut(b,a);
            return;
        }
        while(blen >= 0)
        {
            //cout<<a[a1]<<"--"<<b[b1]<<endl;
            if(a[a1] > b[b1])
            {
                cout<<"-";
                doCut(a,b);
                return;
            }
            if(a[a1++] < b[b1++])
            {
                doCut(b,a);
                return;
            }
            blen--;
        }
        cout<<0<<endl;
    
    }
    
    void doJudge(char *a,char *b)
    {
    
        char d[10005]={''};
        if(a[0] == '-')
        {
            for(int i=1;i<strlen(a);i++)
            {
                d[i-1]=a[i];
            }
            //cout<<endl<<"^^^^"<<d<<endl;
            dothat(d,b);
        }
        else
        {
            for(int i=1;i<strlen(b);i++)
            {
                d[i-1]=b[i];
            }
            dothat(d,a);
        }
    }
    
    
    void init(char *a,char *b)
    {
        for(int i=0;i<10005;i++)
        {
            a[i]='';
            b[i]='';
        }
    }
    
    
    int main()
    {
        char a[10005];
        char b[10005];
    
    
        while(cin>>a>>b)
        {
    
            int c[10005] = {''};
            int a1=0,b1=0;
            int alen = strlen(a) -1;
            int blen = strlen(b) -1;
            int clen=0;
    
            if(a[0]=='-' && b[0]=='-')
            {
                //加法
                if(a[1] !='0' || b[1] !='0')
                    cout<<"-";
                a1++;
                b1++;
            }
            else if(a[0] == '-' || b[0] == '-')
            {
                //减法
                doJudge(a,b);
                init(a,b);
                continue;
            }
    
            int jin = 0;
            //加法
            while(alen>=a1 && blen>=b1)
            {
                c[clen] = a[alen]-'0' + b[blen] -'0' + jin;
                if(c[clen] > 9)
                {
                    jin=1;
                    c[clen] %= 10;
                }
                else
                {
                    jin=0;
                }
                //cout<<c[clen]<<endl;
                clen++;
                alen--;
                blen--;
            }
            while(alen >= a1)
            {
                //cout<<endl<<"alen >= a1"<<endl;
                c[clen] = a[alen--]-'0'+jin;
                if(c[clen] > 9)
                {
                    jin=1;
                    c[clen] %= 10;
                }
                else
                {
                    jin=0;
                }
                clen++;
            }
            while(blen >= b1)
            {
                //cout<<endl<<"blen >= b1"<<endl;
                c[clen] = b[blen--]-'0'+jin;
                if(c[clen] > 9)
                {
                    jin=1;
                    c[clen] %= 10;
                }
                else
                {
                    jin=0;
                }
                clen++;
            }
            if(jin == 1){
                c[clen++] = 1;
            }
            int tt=0;
            int emptyt = 0;
            for(--clen; clen>=0; clen--)
            {
                if(tt==0)
                {
                    if(c[clen] == 0) continue;
                    tt=1;
                }
                emptyt=1;
                cout<<c[clen];
            }
            if(emptyt==0) cout<<0;
    
            cout<<endl;
            init(a,b);
        }
        return 0;
    }
    
    
    
    
    
    
  • 相关阅读:
    深入浅出设计模式——命令模式(Command Pattern)
    深入浅出设计模式——职责链模式(Chain of Responsibility Pattern)
    深入浅出设计模式——代理模式(Proxy Pattern)
    深入浅出设计模式——享元模式(Flyweight Pattern)
    深入浅出设计模式——外观模式(Facade Pattern)
    perl字符串操作符
    perl中单引号和双引号字符串区别
    用例图详解
    perl中system函数和反引号` `使用区别
    window cmd命令行下执行perl语句
  • 原文地址:https://www.cnblogs.com/yinyoupoet/p/13287543.html
Copyright © 2020-2023  润新知