一、 karatsuba multiplication algorithm
(1)Karatsuba算法主要应用于两个大数的相乘,原理是将大数分成两段后变成较小的数位,然后做3次乘法,并附带少量的加法操作和移位操作。
现有两个大数,x,y。
首先将x,y分别拆开成为两部分,可得x1,x0,y1,y0。他们的关系如下:
x = x1 * 10m + x0;
y = y1 * 10m + y0。其中m为正整数,m < n,且x0,y0 小于 10m。
那么 xy = (x1 * 10m + x0)(y1 * 10m + y0)
=z2 * 102m + z1 * 10m + z0,其中:
z2 = x1 * y1;
z1 = x1 * y0 +x0 * y1;
z0 = x0 * y0。
此步骤共需4次乘法,但是由Karatsuba改进以后仅需要3次乘法。因为:
z1 = x1 * y0+ x0* y1
z1 = (x1 + x0) *(y1 + y0) - x1 * y1 - x0 * y0,
故z1 便可以由一次乘法及加减法得到。
(2)复杂度:
普通乘法的复杂度是n2,而Karatsuba算法的复杂度仅为3nlog3≈3n1.585(log3是以2为底的)
#include<iostream>
#include<cmath>
#include<stdio.h>
using namespace std;
//找到x的位数
int size(long x){
int num=0;
do{
num++;
x=x/10;
}while(x);
return num;
}
long Karatsuba(long x,long y)
{
if(x<10 || y<10) return x*y;
else{
long m , x1 , x0 ,y1 , y0 , z0 , z1 , z2 ;
m=max(size(x),size(y))/2;
x1 = x/(int)pow(10,m);
x0 = x-x1*(int)pow(10,m);
y1 = y/(int)pow(10,m);
y0 = y-y1*(int)pow(10,m);
z2 = Karatsuba(x1,y1);
z0 = Karatsuba(x0,y0);
z1 = Karatsuba((x1+x0),(y1+y0))-z2-z0;
return z2*(int)pow(10,2*m)+z1*(int)pow(10,m)+z0;
}
}
int main()
{
long a , b;
cin >> a >> b;
cout << Karatsuba(a,b) << endl;
return 0;
}
参考: http://baike.baidu.com/link?url=YCEEYyFGxpsPkMFUOnOgcvcyrlWV-23bEdqe-AmrHC2SSQyLmzDOX65NGyEeIjwZAJ6ypoQgpx9tYO8u-Rad6K7U8tKe_6Qx0r2a_9kkWohT19y7w2AWRk5DtwSLz-j6
http://blog.csdn.net/maoxunxing/article/details/41308247