算法:Karatsuba算法所提高的运算速率

运算速率

对于大多数人来说两位数的乘法计算大多是这样算的,因为我们从小就这样算。
算法:Karatsuba算法所提高的运算速率_第1张图片
而对于计算机来说由于底层硬件与、或、非门的逻辑,加法一般比乘法所需要的运算速率快且占用逻辑块少。而Karatsuba提出的算法思路如下
算法:Karatsuba算法所提高的运算速率_第2张图片
这样就把两个数的乘法转换为简单的乘法和几个加减法,而对于更大的两个数来说可以想这样一样先将乘数和被乘数分成两份,套用Karatsuba算法计算。也就是说这是一个递归算法。

public static long multiply(long n, long m){
		if((n < 10)|| (m < 10)){
			return n*m;
		}
		int nLength = (n+"").length();
		int mLength = (m+"").length();
		int maxLength = nLength>mLength ? nLength : mLength;
		int maxPart = 0;
		if(maxLength%2 == 0){
			maxPart = maxLength / 2 ;
		}else{
			maxPart = maxLength / 2 + 1;
		}
		Long nH = Long.parseLong((n+"").substring(0,nLength-maxPart));
		Long nL = Long.parseLong((n+"").substring(nLength-maxPart,nLength));
		Long mH = Long.parseLong((m+"").substring(0,mLength-maxPart));
		Long mL = Long.parseLong((m+"").substring(mLength-maxPart,mLength));
		Long a0 = multiply(nH, mH);
		Long a1 = multiply(nL, mL);
		Long aCentre = multiply((nH + nL), (mH + mL));
		//Bigdecimal
		return BigDecimal.valueOf( (a0*Math.pow(10,maxLength)) + 
				((aCentre-a0-a1)*Math.pow(10,maxPart)) + a1).longValue();
	}

这样的话就把两个数分解开并变为简单的乘法和加减法。但是在测试时,发现计算机还是直接乘的速度更快。在之后的查资料才发现这个算法的速率快是建立在20前的硬件水平上的,而在这20年中乘法和加法的运算速率已经大大缩小,甚至在使用某些硬件时可以通过做多次的乘法来提高加法的运算速率。所以硬件开发更加强大了,算法速率也在不断提高。而我们能做的就是努力学习更多知识以助于我们更加强大。努力吧,少年。

参考:https://www.quantamagazine.org/mathematicians-discover-the-perfect-way-to-multiply-20190411/

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