分治算法之两个N位数相乘 Java描述
两个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; } }
运算结果
posted on 2018-08-10 11:34 yfyfyf947 阅读(1114) 评论(0) 编辑 收藏 举报