【問題描述】 設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
#include
using
namespace std;
#define sign(a) ((a > 0) ? 1 : -1)
intintegermultiply
(int x,
int y,
int n)
//引數為大整數 x,y及它們相同的位數 n
}int
main()
cout <<
"x * y = "
<<
integermultiply
(x, y, n)
<< endl;
cout <<
"x * y = "
<< x * y << endl;
return0;
}
分治法 大整數相乘
大整數相乘 a b兩個整數,a有n位 123456 n b有m位 123456 m 一般的思路是像最初學習乘法時一樣逐位相乘後相加,但是這樣做演算法的複雜度過高,但這仍然是解題的基本思想。既然提到分治,那麼如何分,怎麼治?能夠找到乙個大問題劃分為小問題方法的重要技巧是能夠看到大問題的規模和所謂規模的...
大整數相乘 分治法(JS)
相乘的基本原理 如 1234 567第一步 分解 234 12 和 34 567 5 和 67 第二步 分別計算 首部 12 5 60 中部 12 67 34 5 974 尾部 34 67 2278第三步 進製 因為是以兩位數字分割的,所以進製是滿100進一位 尾部 留78,進22,即78 中部 9...
分治法的經典問題 大整數相乘
討論問題時,先來了解一下什麼是分治法。分治法的意思就是,分而治之,也就是把乙個問題,拆分成幾個小問題,最後再彙總解決的方法 假如現在我們要求兩個大整數相乘的乘積,如1234 1234 這裡為了了分析簡便,所以不舉形如1234567891234567這樣的大整數,不必要在此糾結 那麼按照我們小學學的乘...