热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

分治算法之两个N位数相乘Java描述

两个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;
    }
}

运算结果

 


推荐阅读
author-avatar
如哽在喉_495
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有