prod是采用一般的O(n^2)bigInt乘法算法, multiply用分治做了优化,时间开销介于O(n^1.5)到O(n^2)之间,具体是多少忘了
string Plus(const string &num1,const string num2)
{
if(num1.length()<num2.length()) return Plus(num2,num1);
string res(num1.length()+1,' ');
int carry=0,i=num1.length()-1,j=num2.length()-1;
while(i>=0){
int n1 = num1[i] - '0',n2 = 0;
if(j>=0) n2 = num2[j] - '0';
int k= n1+n2+carry;
carry = k/10; k%=10;
res[i+1] = k + '0';
i--; j--;
}
if(carry>0) res[0] = carry + '0';
else res.erase(res.begin());
return res;
}
string Minus(const string &num1,const string &num2){
if(num1.length()<=num2.length()){
if((num1.length()==num2.length()&&num1<num2)
||num1.length()<num2.length())
{
string ret;
ret.push_back('-');
ret.append(Minus(num2,num1));
return ret;
}
}
string ret(num1.length(),' ');
int i=num1.length()-1,j=num2.length()-1;
int cur,carry=0;
for(;i>=0;i--,j--){
int k='0';
if(j>=0) k=num2[j];
cur=num1[i]-carry-k;
if(cur<0){ cur+=10; carry=1;}
else carry=0;
ret[i]=cur+'0';
}
while(ret[0]=='0'&&ret.length()>1) ret.erase(0,1);
return ret;
}
string prod(const string &num1, int num2)
{
if(num2==0) return "0";
if(num2==1) return num1;
string res(num1.length()+1,' ');
int carry=0;
for(int i=num1.length()-1;i>=0;i--){
int c = num1[i]-'0';
int k = c*num2 + carry;
carry = k/10; k%=10;
res[i+1] = k + '0';
}
if(carry!=0) res[0] = carry + '0';
else res.erase(res.begin());
return res;
}
string prod(const string &num1,const string &num2)
{
string res = "0";
for(int i=num2.length()-1;i>=0;i--){
string tmp = prod(num1,num2[i]-'0');
tmp.append(num2.length()-i-1,'0');
res = Plus(tmp,res);
}
return res;
}
string multiply(const string &num1, const string &num2) {
if(num1.length()<num2.length()) return multiply(num2,num1);
string ret;
if(num1.length()+num2.length()<=50) return prod(num1,num2);
string n2;
int k=0;
while(k<num1.length()-num2.length()){ n2.push_back('0');k++;}
n2.append(num2);
int L=num1.length()/2;
string a=num1.substr(0,L),
b=num1.substr(L,num1.length()-L),
c=n2.substr(0,L),
d=n2.substr(L,num1.length()-L);
string ac=multiply(a,c),
bd=multiply(b,d),
t1=multiply(Plus(b,a),Plus(c,d)),
t2=Plus(ac,bd),
bcPad=Minus(t1,t2);
k=0;
while(k<2*(num1.length()-L)){ ac.push_back('0');k++;}
k=0;
while(k<num1.length()-L){ bcPad.push_back('0'); k++;}
ret=Plus(ac,bcPad);
ret=Plus(ret,bd);
return ret;
}