设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.运行结果
注:因为c语言本身程序计算位数有限,会产生数据溢出。所以以下结果也是正常的。但在Python环境下就可无限计算。
将代码转成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))