分治算法案例四:大整数乘法

大整数乘法实现复数乘积

  • 设x = a+bi 和 y = c+di是两个复数(设a、b、c和d均为n位整数)。采用蛮力算法需要进行4次n位整数乘法以计算乘积 ,也就是 xy = (ac-bd)+(ad+bc)i。请设计一个算法,要求只用3次n位整数乘法计算乘积 。

(1).算法设计思路
大数相乘:如1234,将其分割为两部分,12和34,获取34的字符长度length = 2,然后1234 = 12 x10length。递归的边界条件是当输入的数据的长度为1或2时,此时数据较小,可直接相乘得到结果。当数据较大时,就获取两个大数的两部分,A,B,C,D。A、C分别除以10length得到两个数的前半部分,B、D分别对10length取模得到后半部分。
通过推出来的公式:2 x AC x 10n+m + (A x 10n-B)(D - C x 10m) + 2 x BD得到结果。其中n、m分别为B、D的长度。(可实现不同位数的相乘)

复数相乘:接收两个复数的实部和虚部,并由公式(a+bi)(c+di)=ac-bd+[(a-b)(d-c)+ac+bd]i
调用大数相乘multiply得到a x c、b x d、(a-b) x (d-c)的结果并返回复数的乘积
(2).算法实现代码

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int a = in.nextInt();
		int b = in.nextInt();
		int c = in.nextInt();
		int d = in.nextInt();
		System.out.println(multi(a,b,c,d));	}
	private static String multi(int a,int b,int c,int d) {
		/*
		 * (a+bi)(c+di) = ac-bd+[(a-b)(d-c)+ac+bd]i
		 */
		long ac = multiply(a,c);
		long bd = multiply(b,d);
		long xx = multiply((a-b),(d-c)) +ac+bd;
		//判断虚部的符号,若为正,则添加一个+  若为负,则不需要添加加号
		return xx > 0? ac-bd+"+"+xx+"i":ac-bd+""+xx+"i";
	}
	private static long multiply(long x,long y) {
		/*	  x = A | B		
		 *    y = C | D
		 */
		//获取x中B部分的长度,y中D部分的长度
		long n = String.valueOf(x).length() - String.valueOf(x).length()/2;
		long m = String.valueOf(y).length() - String.valueOf(y).length()/2;
		//当输入的数长度为1或2时,直接相乘
		if(String.valueOf(x).length()/2 == 1||String.valueOf(x).length()/2 == 0)
			return x*y;
		
		long A = (long) (x/Math.pow(10, n));//获取A部分
		long B = (long) (x%Math.pow(10, n));//获取B部分
		long C = (long) (y/Math.pow(10, m));//获取C
		long D = (long) (y%Math.pow(10, m));//获取D
		//由蛮力算法的公式(A*10^n + B)(C*10^m + D) --> AC*10^(n+m) +AD*10^n +BC*10^m +BD
		//转化为三次乘法:--->AC*10^(n+m) +(A*10^n -B)(D - C*10^m) +AC*10^(m+n) +BD +BD
		//			 --->2*AC*10^(n+m) +(A*10^n -B)(D - C*10^m) +2*BD
		long AC = (long) (2*multiply(A,C)*Math.pow(10, m+n));
		long BD = 2*multiply(B,D);
		long XX = multiply((long)(A*Math.pow(10, n)-B),(long)(D-C*Math.pow(10, m)));
		
		return AC+XX+BD;
		
	}
}

假设计算的两个数都为n位。由公式可知它仅需做3次n/2次整数的乘法,6次加减法和2次移位。则
T(n) = 3 x T(n/2)+O(n)

你可能感兴趣的:(算法设计)