递归与分治之大整数乘法

大整数乘法

现在我们给出两个数字1234和4321(这两个数字并不大,以此为例而已),按照我们做乘法的习惯,我们写成竖式,用1234分别跟4,3,2,1相乘并对应移位相加得到结果,那么我们在这个过程中用了几次乘法呢?是4次?不,其实1234跟4相乘是1,2,3,4分别乘4,也是4次乘法,因此一共我们使用了4*4次乘法。

这仅仅是4位,如果是更多,那么算法的复杂度无疑是O(n^2),为了提高效率,降低这种复杂度,我们可以使用分治法。

首先,我们将两个n位大整数X,Y分开,分为四个n/2位的整数,如下:
在这里插入图片描述
例如,X=12345678,分成a=123410^4,b=56781;此时的计算效率如下:
在这里插入图片描述
利用我们学过的复杂度分析法,其复杂度如下:
在这里插入图片描述
根据master定理,复杂度为O(n^2),并没有改进。

为了降低复杂度,我们必须用加法代替乘法,因此我们修改一下上面式子的形式:
在这里插入图片描述
在这里插入图片描述
补充:master定理:

在这里插入图片描述
代码摘自:https://blog.csdn.net/jeffleo/article/details/53446095

#include<cstdio>
#include<cmath>

using namespace std;

#define SIGN(A) ((A > 0) ? 1 : -1) 
int divideConquer(int X, int Y, int n){
    int sign = SIGN(X) * SIGN(Y);
    int x = abs(X);
    int y = abs(Y);
    if(x == 0 || y == 0){
        return 0;
    }else if(n == 1){
        return sign * x * y;
    }else{
        int A = (int) x / pow(10, (int)(n / 2));
        int B = x - A * pow(10, n / 2);
        int C = (int) y / pow(10, (int)(n / 2));
        int D = y - C * pow(10, n / 2);
        int AC = divideConquer(A, C, n / 2);
        int BD = divideConquer(B, D, n / 2);
        int ABDC = divideConquer((A - B), (D - C), n / 2) + AC + BD;
        return sign * (AC * pow(10 , n) + ABDC * pow(10, (int)(n / 2)) + BD); 
    }
}

int main(){
    int x, y, n;
    scanf("%d%d%d", &x, &y, &n);
    printf("x 和 y的乘积为:%d", divideConquer(x, y, n));
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值