karatsuba算法(大整数乘法)

Karatsuba算法

  • Karatsuba算法主要应用于两个大数的相乘,原理是将大数分成两段后变成较小的数位,然后做3次乘法,并附带少量的加法操作和移位操作。
    karatsuba算法(大整数乘法)_第1张图片
    karatsuba算法(大整数乘法)_第2张图片
    可以将X,Y,分开来计算,同时对于AD+BC
    在这里插入图片描述
    可以采用已经计算过的AC,BD,来表示进一步减少程序的运算量和复杂度

Karatsuba乘法求解步骤:

  • 1、分解。将大整数X、Y(分别为n,m位)分别为A、B、C、D。值得注意的是如果位数n或m为奇数,则A为前n/2+1或m/2+1位,n/2或m/2向下取整;

  • 2、计算。分别计算AC、BD,并且利用AC和BD计算AD+BC;

  • 3、求解。

1.理想化的情况,两个大整数的位数相同

由以上可以得出在此情况下的计算公式:
karatsuba算法(大整数乘法)_第3张图片

代码实现:

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

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

        //拆分为a,b,c,d
        BigInteger a = new BigInteger(num1.toString().substring(0, size1 - halfN));
        BigInteger b = new BigInteger(num1.toString().substring(size1 - halfN));
        BigInteger c = new BigInteger(num2.toString().substring(0, size2 - halfN));
        BigInteger d = new BigInteger(num2.toString().substring(size2 - halfN));

        BigInteger ac = karatsuba(a, c);
        BigInteger bd = karatsuba(b, d);
        BigInteger ad_add_bc = karatsuba((a.add(b)), (c.add(d))).subtract(a.multiply(c)).subtract(b.multiply(d));

        return (BigInteger) (a.multiply(c).multiply(BigInteger.valueOf((long) Math.pow(10, 2 * halfN)))
                .add(ad_add_bc.multiply(BigInteger.valueOf((long) Math.pow(10, halfN)))))
                .add(bd);
    }


    /**
     * Karatsuba乘法
     */
    public static long karatsuba1(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));

        // 计算ac, bd, ad_add_bc, 此处的乘法使用递归
        long ac = karatsuba1(a, c);
        long bd = karatsuba1(b, d);
        long ad_add_bc = karatsuba1((a + b), (c + d)) - bd - ac;

        return (long) (ac * Math.pow(10, (2 * halfN)) + ad_add_bc * Math.pow(10, halfN) + bd);
    }

参考:https://blog.csdn.net/m0_52048415/article/details/123564370

你可能感兴趣的:(算法,算法)