java实现大数相乘的2种方式

按位运算–时间效率O(n^2)

import java.util.LinkedList;
import java.util.List;

public class first {
    public static List<Integer> bigNumberMultiply2(int[] num1, int[] num2){
        // 分配一个空间,用来存储运算的结果,num1长的数 * num2长的数,结果不会超过num1+num2长
        LinkedList<Integer>result = new LinkedList<>();
        // 先不考虑进位问题,根据竖式的乘法运算,num1的第i位与num2的第j位相乘,结果应该存放在结果的第i+j位上
        for (int i = 0; i < num1.length; i++){
            for (int j = 0; j < num2.length; j++){
                if(result.size()-1<i+j)
                    result.add(0);
                result.set( i+j, result.get(i+j)+(num1[i] * num2[j])%10);
                // 需要进位
                if((num1[i] * num2[j])/10>0) {
                    if(result.size()-1<i+j+1)
                        result.add(0);
                    result.set(i + j + 1, result.get(i + j + 1) + (num1[i] * num2[j]) / 10);
                }
            }
        }
        return result;
    }
    public static void main(String[]args){
        List<Integer>res = bigNumberMultiply2(new int[]{3,2},new int[]{3});
        for(int i:res)
            System.out.print(i);
    }
}

分治乘法–Karatsuba算法

参考资料:https://blog.csdn.net/u010983881/article/details/77503519
每个字符串分成2个片段

import java.math.BigInteger;

public class first {
    static String add(String a, String b) {
        if (a.length() <= 8 && b.length() <= 8)
            return Integer.parseInt(a) + Integer.parseInt(b) + "";
        String a1 = "0";
        String a2 = a;
        if (a.length() > 8) {
            a1 = a.substring(0, a.length() - 8);
            a2 = a.substring(a.length() - 8);
        }
        String b1 = "0";
        String b2 = b;
        if (b.length() > 8) {
            b1 = b.substring(0, b.length() - 8);
            b2 = b.substring(b.length() - 8);
        }
        String t = add(a2, b2);
        while (t.length() < 8)
            t = "0" + t;
        if (t.length() > 8)
            return add(add(a1, b1), "1") + t.substring(1);
        return add(a1, b1) + t;
    }

    static String multi(String a, String b) {
        if (a.length() <= 4 && b.length() <= 4)
            return Integer.parseInt(a) * Integer.parseInt(b) + "";
        if (a.length() > 4) {
            int k = a.length() / 2;
            String a1 = a.substring(0, k);
            String a2 = a.substring(k);
            String tmp = multi(a1, b) + zero(a2.length());
            String tmp1 = multi(a2, b);
            return add(tmp,tmp1 );
        }
        return multi(b, a);
    }

    static String zero(int n) {
        if (n == 0) return "";
        if (n == 1) return "0";
        String s = zero(n / 2);
        return s + s + zero(n % 2);
    }

    public static void main(String[] args) {
        System.out.println(multi("123456789","987654321"));
        System.out.println(new BigInteger("123456789").multiply(new BigInteger("987654321")));
    }
}

/**
 * Karatsuba乘法
 */
public static long karatsuba(long num1, long num2){
    //递归终止条件
    if(num1 < 10 || num2 < 10) return num1 * num2;

    // 计算拆分长度
    int size1 = String.valueOf(num1).length();
    int size2 = String.valueOf(num2).length();
    int halfN = Math.max(size1, size2) / 2;

    /* 拆分为a, b, c, d */
    long a = Long.valueOf(String.valueOf(num1).substring(0, size1 - halfN));
    long b = Long.valueOf(String.valueOf(num1).substring(size1 - halfN));
    long c = Long.valueOf(String.valueOf(num2).substring(0, size2 - halfN));
    long d = Long.valueOf(String.valueOf(num2).substring(size2 - halfN));

    // 计算z2, z0, z1, 此处的乘法使用递归
    long z2 = karatsuba(a, c);
    long z0 = karatsuba(b, d);
    long z1 = karatsuba((a + b), (c + d)) - z0 - z2;

    return (long)(z2 * Math.pow(10, (2*halfN)) + z1 * Math.pow(10, halfN) + z0);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

广大菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值