使用list保证时间效率,分治实现c++ bigInteger

#include <iostream>
#include <string>
#include <list>
using namespace std;


//三个数相加求低位
char add_gw(char a,char b,char c)
{
    return ((a-'0')+(b-'0')+(c-'0'))%10+'0';
}

//三个数相加求高位
char add_sw(char a,char b,char c)
{
    return ((a-'0')+(b-'0')+(c-'0'))/10+'0';
}

//这里实现多位数相加,后向前遍历string
string add(string a,string b)
{
    list<char> sum;
    if(a.length()<b.length())
        a.swap(b);
    string::reverse_iterator a_i = a.rbegin();
    //进位数字
    char temp='0';
    for(string::reverse_iterator b_i=b.rbegin();b_i<b.rend();b_i++)
    {
        //插入到前面
        sum.push_front(add_gw(*a_i,*b_i,temp));
        temp = add_sw(*a_i,*b_i,temp);
        a_i++;
    }
//b的位数比较短,先遍历完了,之后把进位和a的剩余位数加完。
for(;a_i<a.rend();a_i++) { sum.push_front(add_gw(*a_i,'0',temp)); temp = add_sw(*a_i,'0',temp); }
  //看看进位是不是非零。
if(temp != '0') sum.push_front(temp);

  //将list 转化为string
string str_sum; for(list<char>::iterator i=sum.begin();i!=sum.end();i++) { str_sum.push_back(*i); } return str_sum; } //两位数乘法得到个位 char mul_gw(char a,char b) { return ((a-'0')*(b-'0'))%10+'0'; }
//两位数乘法得到十位
char mul_sw(char a,char b) { return ((a-'0')*(b-'0'))/10+'0'; } //向左移位操作操作 string & yiwei(string &a,int weishu) { if(a.length()>0 && a.at(0) != '0') { for(int i=0;i<weishu;i++) { a.push_back('0'); } } return a; }
//乘法
string multiply(string a,string b) { string sum; if(a.length()<b.length()) a.swap(b); if(b.length() == 0) { sum = "0"; return sum; } if(a.length()==1) { char temp = mul_sw(a[0],b[0]); if(temp != '0') sum.push_back(temp); sum.push_back(mul_gw(a[0],b[0])); return sum; }
//a的长度超过1就折半分别求
if(a.length()>1) { string a1 = a.substr(0,a.length()/2); string a2 = a.substr(a.length()/2,-1); string b2; string b1; if((a.length()+1)/2>b.length()) { b2 = b; b1.clear(); } else { b2 = b.substr(b.length()-(a.length()+1)/2,-1); b1 = b.substr(0,b.length()-(a.length()+1)/2); }

//这里为了调试才这么写,其实可以一次性写完的。
string x1 = yiwei(multiply(a1,b1),a2.length()*2); string x2 = yiwei(multiply(a1,b2),a2.length()); string x3 = yiwei(multiply(a2,b1),a2.length()); string x4 = multiply(a2,b2); string x5 = add(x1,x2); string x6 = add(x3,x4); string x7 = add(x5,x6); return x7; } } int main() { string a,b; cin>>a>>b; cout<<multiply(a,b)<<endl; getchar(); getchar(); return 0; }

 

由于string是由数组实现的,因此push_front的时间复杂度O(n),n歌就是O(n^2),改用list,只要最后转成string只用O(n)。

 

这里简介里面的递归算法,

 

将大数A,B分成两段,后面段的长度为x。如图:

 

好了,一切明了。

 

 

posted @ 2013-05-06 16:51  chengzheqiao  阅读(260)  评论(0编辑  收藏  举报