请设计一个有效的算法,可以进行两个n位大整数的乘法运算
1 最暴力的方法:O(n^2)
2 我们采用分而治之的思想
将X和Y按如下方法分成两部分
那么
X = A*10^(n/2) + B
Y = C*10^(n/2) + D
X*Y = (A*10^(n/2) + B)*( C*10^(n/2) + D)
= A*C*10^n + A*D*10^(n/2) + B*C*10^(n/2) + B*D
复杂度分析
为了降低时间复杂度,必须减少乘法的次数
上式可改写为
X*Y = (A*10^(n/2) + B)*( C*10^(n/2) + D)
= A*C*10^n + A*D*10^(n/2) + B*C*10^(n/2) + B*D
= A*C*10^n + ((A+B)(C+D) – A*C – B*D)*10*(n/2) + B*D
或者
= A*C*10^n + ((A-B)(D-C) + A*C + B*D)*10*(n/2) + B*D
复杂度分析
Java代码
package powernumber;
/**
* 大整数相乘
* @author Dudu
* @date 2018-11-10
*/
public class BigDataRide {
public static int sign(long a) {
return a < 0 ? -1 : 1;
}
public static double bigdataride(long x,long y,int n) {
x = Math.abs(x);
y = Math.abs(y);
if (n == 1) {
return x * y;
}
else {
if (n%2==1) {
n = n - 1; //对奇数的操作
}
long a = x / Math.round(Math.pow( 10 , (n / 2)));
long b = x - a * Math.round(Math.pow( 10 , (n / 2)));
long c = y / Math.round(Math.pow( 10 , (n / 2)));
long d = y - c * Math.round(Math.pow( 10 , (n / 2)));
double ac = bigdataride(a,c,n/2);//递归计算a*c
double bd = bigdataride(b,d,n/2);//计算b*d
long aJb = a + b;
long cJd = c + d;
double abcd = bigdataride(aJb,cJd,n/2);
return (ac*Math.pow(10,n) + (abcd - ac - bd)*Math.pow(10,n/2) +bd);
}
}
public static void main(String[] args) {
// 大整数相乘
long x = 12234L;
long y = 45243L;
String sx = String.valueOf(x);
int n = sx.length();
long sig = sign(x)*sign(y);
double s = bigdataride(x,y,n);
System.out.println("大数相乘的计算结果为:"+s*sig);
}
}
输出的结果为:5.53502862E8