分治法求解大整数相乘问题

分治法求解大整数相乘问题

【问题描述】 设X和Y都是n位的大整数,现在要计算它们的乘积XY。

【提示】采用分治法求解两个十进制大整数的乘法,以提高乘法的效率,减少乘法次数。
计算公式为:
XY=AC10n+[(A-B)(D-C)+AC+BD]10n/2+BD
下面的例子演示了分治算法的计算过程。
设X=314l,Y=5327,用上述算法计算XY的计算过程可列表如下,其中带’号的数值是在计算完成AC,BD,和(A-B)(D-C)之后才填入的。


X=3141 A=31 B=41 A-B=-10
Y=5327 C=53 D=27 D-C=-26
AC=(1643)’
BD=(1107)’
(A-B)(D-C)=(260)’
XY=(1643)‘104+[(1643)’+(260)‘+(1107)’]102+(1107)’
=(16732107)’


A=31 A1=3 B1=1 A1-B1=2
C=53 C1=5 D1=3 D1-C1=-2
A1C1=15 B1D1=3 (A1-B1)(D1-C1)=-4
AC=1500+(15+3-4)10+3=1643


B=41 A2=4 B2=1 A2-B2=3
D=27 C2=2 D2=7 D2-C2=5
A2C2=8 B2D2=7 (A2-B2)(D2-C2)=15
BD=800+(8+7+15)10+7=1107


|A-B|=10 A3=1 B3=0 A3-B3=1
|D-C|=26 C3=2 D3=6 D3-C3=4
A3C3=2 B3D3=0 (A3-B3)(D3-C3)=4
(A-B)(D-C)=200+(2+0+4)10+0=260

【算法时间复杂度分析】
该算法仅需做3次n/2位整数的乘法(AC,BD和(A-B)(D-C)),6次加、减法和2次移位的运算。所以,该算法时间复杂度为:
T(n)=O(nlog3)=O(n1.59)

//代码如下
/*
函数功能:分治法求两个N为的整数的乘积
输入参数:X,Y分别为两个N位整数
算法思想:
时间复杂度为:T(n)=O(nlog3)=O(n1.59)
*/

#include<iostream>
#include<math.h>
using namespace std;

#define SIGN(A) ((A > 0) ? 1 : -1)			
int IntegerMultiply(int X, int Y, int N)	//参数为大整数 X,Y及它们相同的位数 N 
{
	int sign = SIGN(X) * SIGN(Y);			//确定两数乘积的正负 
	int x = abs(X);							//将两数化为绝对值,之后计算再加入正负号 
	int y = abs(Y);
	if((x == 0) || (y == 0))				//乘数有一个为 0,两数相乘为 0 
		return 0;
	if (N == 1)								//只剩一位时,返回 
		return sign * x * y;
	else
	{
		int A = x / pow(10, N/2);     		
		int B = x - A * pow(10, N/2); 
		int C = y / pow(10, N/2);    
		int D = y - C * pow(10, N/2);
		
		int AC = IntegerMultiply(A, C, N/2);   
		int BD = IntegerMultiply(B, D, N/2);
		int ADBC = IntegerMultiply(A - B, D - C, N/2) + AC + BD;
		return sign * (AC * pow(10, N) + ADBC * pow(10, N/2) + BD); //可根据公式化简 
	}
}

int main()
{
	int x, y, z, n = 0;
	cin >> x >> y;
	
	z = x;
	while(z != 0)			// 求 X,Y有多少位 
	{
		z = z / 10;
		++n;
	}

	cout << "x * y = " << IntegerMultiply(x, y, n) << endl;
	cout << "x * y = " << x * y << endl;
	return 0;
}
  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值