karatsuba算法——(分治算法)

一、     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
#include
#include 
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

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