分治递归————大整数乘法

大整数乘法(分治)

算法分析

设x,y十进制整数,计算乘积xy。
用小学方法设计算法,计算步骤太多,而且效率低。T(n)=O(n^2)
所以用分治方法设计更有效的大整数乘法。将n为十进制整数x,y分为两段,每段长为n/2(若位数为奇数,每段长为[n/2],[n/2]+1)。x分为A和B,y分为C和D.比如 8945456 ,即A=89,B=45,C=4,D=56.
引入公式:
XY=AC
(n^2 +((A-B)(D-C)+AC+BD)*2^(n/2)+BD
看起来似乎更复杂,其实只需要做三次n/2为整数的乘法。T(n)=O(n^log3)

代码设计

1.函数库引入,预编译。

#include
#include

2.因为要对非2^n求解,所以引入整数位数,若为奇数,则分为不相等位数的两个数字。若想等,则直接分为位数相等的两个整数。

int Place(x)   //求x是多少位数(10位数以内)
{
	int n=0;
	while(x>0)
	{
		n++;
		x/=10;
	}
	return n;
}

3.位数求解后,直接使用公式求解。

int Bignum(int x,int y)
{
	int n,m,a,b,c,d,p1,p2,p3;
	if(Place(x)<=2||Place(y)<=2)
		return x*y;
	else
	{
		n=Place(x)/2;   m=Place(y)/2;
		//printf("%d,%d\n",n,m);

		a=x/pow(10,n);  b=x-a*pow(10,n);  //a是x前半部分,b是x后半部分
		c=y/pow(10,m);  d=y-c*pow(10,m);  //c是y前半部分,d是y后半部分
	
		p1=Bignum(a,c);     //递归运算ac,bd,(a-b)(d-c)
		p2=Bignum(b,d);
		p3=Bignum(a-b,d-c);
		return p1*pow(10,2*n)+(p3+p1+p2)*pow(10,n)+p2;
	}
}

4.完成函数调用,求解乘积。

void main()
{
	int x,y,p;
	scanf("%d%d",&x,&y);
	p=Bignum(x,y);
	printf("%d\n",p);
}

5.运行结果
分治递归————大整数乘法_第1张图片
注:因为c语言本身程序计算位数有限,会产生数据溢出。所以以下结果也是正常的。但在Python环境下就可无限计算。
分治递归————大整数乘法_第2张图片
将代码转成python

def Place(x):   #求x是多少位数(10位数以内)

	n=0;
	while x>0:
	    n=n+1
	    x=int(x/10)
	return n

def Bignum(x,y):

	#int n,m,a,b,c,d,p1,p2,p3;
	if(Place(x)<=2 or Place(y)<=2):
	    return x*y
	else:
	    n=int(Place(x)/2)
	    m=int(Place(y)/2)
	    a=int(x/pow(10,n))
	    b=x-a*pow(10,n)  #a是x前半部分,b是x后半部分
	    c=int(y/pow(10,m))
	    d=y-c*pow(10,m)  #c是y前半部分,d是y后半部分
	    p1=Bignum(a,c)    #递归运算ac,bd,(a-b)(d-c)
	    p2=Bignum(b,d)
	    p3=Bignum(a-b,d-c)
	return p1*pow(10,2*n)+(p3+p1+p2)*pow(10,n)+p2
x=int(input("x="))
y=int(input("y="))
print(Bignum(x,y))

运行结果
分治递归————大整数乘法_第3张图片

你可能感兴趣的:(分治递归————大整数乘法)