作者:如哽在喉_495 | 来源:互联网 | 2023-10-14 16:35
两个N位数a和b相乘,手算的话一般是a的末位分别乘以b的末位到首位,然后a的倒数第二位分别乘以b的末位到首位,直到a的首位分别乘以b的末位到首位,最后按位数相加。这个过程的时间复杂度是O(n2)的。
两个N位数a和b相乘,手算的话一般是a的末位分别乘以b的末位到首位,然后a的倒数第二位分别乘以b的末位到首位,直到a的首位分别乘以b的末位到首位,最后按位数相加。这个过程的时间复杂度是O(n2)的。
现考虑分治算法,可以将时间复杂度降到亚二次。例如a=61438521,a的左半部分为al=6143,右半部分为ar=8521,b=94736407,bl=9473,br=6407;于是 a*b=al*bl*108+(al*br+ar*bl)*104+ar*br;总共有4次乘法,每次处理的数都是原来的一般,这样还是O(n2)的时间复杂度,考虑到 al*br+ar*bl=(al-ar)*(br-bl)+al*bl+ar*br,因为后两项都是之前要用到的结果,这样就可以吧乘法次数降为3次,时间复杂度为O(nlg3)。
public class twoNumMultiply {
public static void main(String[] args) {
String a="61438521";
String b="94736407";
System.out.println(multiply(a,b));
}
public static long multiply(String a,String b) {
if(Integer.parseInt(a)==0||Integer.parseInt(b)==0) {
return 0;
}
if(a.length()==1&&b.length()==1) {
return Integer.parseInt(a)*Integer.parseInt(b);
}
String al=a.substring(0, a.length()/2);
String ar=a.substring(a.length()/2, a.length());
String bl=b.substring(0, b.length()/2);
String br=b.substring(b.length()/2, b.length());
long albl=multiply(al,bl);
long arbr=multiply(ar,br);
//D3=(al-ar)*(br-bl)+al*bl+ar*br
long D3=(Integer.parseInt(al)-Integer.parseInt(ar))*(Integer.parseInt(br)-Integer.parseInt(bl))+albl+arbr;
int power1= (int) Math.pow(10, 2*ar.length());
int power2=(int)(Math.pow(10, ar.length()));
return albl*power1+D3*power2+arbr;
}
}
运算结果