大数运算之高精度加减法

C++和C中经常有大数运算,

大数就是,这个long long型都存不下的数嘛。那么怎么对他们进行运算呢。

思想如下:
我们一定要用一个什么来存这个大数的各个位。模拟竖式加减法。从最低位开始,因此我们要将这个存放大数位数的东西倒置过来。

大数加法

比如 1234567+789
就可以写成如下形式
7 6 5 4 3 2 1
9 8 7
7+9=16
6存入新的容器里面去。向下进一个1,依次类推。
大抵模拟就是这样。

我之前是用数组慢慢存放。字符数组转化成整数数组。模拟再加减。这样很好实现,只不过,代码太过于冗杂。今天也是在师父的指导下,开始用string这个类,来写这个大数加减。
虽然先开始我觉得这样写很赖皮,不过实在是,比我之前用的方法简单多了。所以不好意思贴我之前用数组写的代码了。很low.

主要代码如下:
既然说倒置了。。前面可以用reverse() 加法当然首先reverse就好。

string Add(string &a,string &b){
    string sum;
    int carry=0;
    //模仿竖式加法。从低位加起,所以倒置 
    reverse(a.begin(),a.end());
    reverse(b.begin(),b.end());

    for(int i=0;iif(i'0';        //先将a[i]变成数字 
        if(i'0';        //再将b[i]变成数字 

        sum+=carry%10+'0';          //相加再变成字符 
        carry/=10;                  //判断相加是否大于10 
    }
    if(carry)
        sum+='1'; 
    reverse(sum.begin(),sum.end());
    return sum; 
}

carry的作用是表示是否进位。carry是int型,所以要在字符和数字间做交换。

最后还要记得做一个判断。
如果最高位上的还要+1,那么这个sum后面当然也要添一个’1’啦。

加法的思想就是这样。。减法有点难想,毕竟我粗心,而且对string用的不熟,以至于十二点才把题给过了。

大数减法

减法也是同样模拟竖式运算。
123456-789
6 5 4 3 2 1
9 8 7 -
6-9=-3。这里不同的就是,要把-3+10=7,存入sum里面才行。

减法的判断有点多,首先判断两个字符串的长度,a

int i=0;    
        for(i=0;i<a.length()||i<b.length();i++){
            if(i'0';
            if(i'0';    
            if(carry<0){
                sum+=carry+10+'0';
                carry=-1;
            }else{
                sum+=carry+'0';
                carry=0;
            }
        }

至于carry为什么要先加a[i]再-b[i]。这个也是模拟的减法运算。 要注意的就是,carry是一个表示是否向前借位的值。之前这里不是很明白,所以出了很多错。carry会有两种值,-1和0。同样也要在字符和整数中做交换。
还有一个地方困惑了很久的就是,我要怎么保证b读完的时候,a还能继续读。之前i

int ind=-1;
        while(sum[++ind]=='0');
        if(ind!=-1)
            sum=sum.substr(ind);

总而言之,今天虽然弄到很晚,还是收获满满。
string真是很好用的东西。

这里贴一个OJ。来自TK-Xiong.
[http://oj.tk-xiong.com/]
大一新手,有错误还请指出、、也许还可以再改进。

你可能感兴趣的:(算法)