大整数乘法

21 篇文章 1 订阅

大整数乘法

题目描述

使用分治算法实现两个大整数相乘。

算法分析
这里写图片描述

使用分治解决两个位数为2的N次方倍的大整数相乘:

这里写图片描述

分析:

看起来好像有点变化,分析一下:对这个式子,我们一共要进行4次 n / 2的乘法(AC2次, AD, BC)和 3次加法,因而该算法的时间复杂度为:

T(n) = 4 * T(n / 2) + θ(n)
通过master定理可以求得 T(n) = θ(n ^ 2),跟小学算法的时间复杂度没有区别。

改进:

但是我们再来看看,我们是否可以用加法来换取乘法?因为多一个加法操作,也是常数项,对时间复杂度没有影响,如果减少一个乘法则不同。

现在的时间复杂度为:

T(n) = 3 * T(n / 2) + θ(n),通过master定理求得,T(n) = O(n^log2(3) ) = O(n^1.59 )。

输入

两个十进制大整数,满足每一个整数长度为2^n且两个大整数的长度相等。(多组数据)

输出

两个大整数的乘积。

样例输入
1234 5678
样例输出
7006652
Code
package Week8;

import java.util.Scanner;
//两个十进制大整数,满足每一个整数长度为2^n且两个大整数的长度相等
public class QB {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //DecimalFormat df   = new DecimalFormat("######0");
        while(sc.hasNext()){
            long num1,num2;
            num1 = sc.nextInt();
            num2 = sc.nextInt();
            int sum_n1,sum_n2;
            sum_n1 = sum_len(num1);
            sum_n2 = sum_len(num2);
//            System.out.println(sum_n1);
//            System.out.println(sum_n2);
            if(sum_n1==sum_n2){
                if(!(Judge(sum_n1)&&Judge(sum_n2))){
                    System.out.println(Calculate(num1,num2,sum_n1));
                }
            }
        }
    }
    //判断整数位数是否为2的n次方
    public static boolean Judge(int n){
        if(n<=1){
            return true;
        } else {
            if(n%2==0){
                n/=2;
                Judge(n);
            }
        }
        return false;
    }
    //计算整数长度
    public static int sum_len(double n){
        int sum = 0;
        for(double i=n;i>1;i/=10){
            sum++;
        }
        return sum;
    }
    //建立一个符号函数
    public static int sign(double n){
        return n>0?1:-1;
    }
    public static long Calculate(long x,long y,int n){
        //符号位
        int sign = sign(x)*sign(y);
        x = Math.abs(x);
        y = Math.abs(y);
        if(x==0||y==0){
            return 0;
        }else if(n==1){
            return sign*x*y;
        }else {
            //Math.pow的计算结果默认类型为double
            long A = (long) (x/ Math.pow(10,n/2));
            long B = (long) (x%Math.pow(10,n/2));
            long C = (long) (y/Math.pow(10,n/2));
            long D = (long) (y%Math.pow(10,n/2));
            long AC = Calculate(A,C,n/2);
            long BD = Calculate(B,D,n/2);
//            //System.out.println((A-B)*(D-C));
//            System.out.println(AC);
            long ABDC = Calculate((A - B), (D - C), n / 2) + AC + BD;
            return (long) (sign * ((AC * Math.pow(10 ,n) + ABDC * Math.pow(10, (n / 2)) + BD)));
        }
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值