分治算法之两个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编辑  收藏  举报