karatsuba算法(大整数乘法)

Karatsuba算法

  • Karatsuba算法主要应用于两个大数的相乘,原理是将大数分成两段后变成较小的数位,然后做3次乘法,并附带少量的加法操作和移位操作。
    在这里插入图片描述
    在这里插入图片描述
    可以将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乘法
     */
    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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

amant 柒少

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

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

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

打赏作者

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

抵扣说明:

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

余额充值