大整数相乘

分治算法介绍 
给定两个n位的二进制整数x和y(当然次算法不限定二进制数),作为x乘y的第一步,我们将x和y一分为二,每个数的左半部分和右半部分都是n/2位的二进制整数: 
这里写图片描述 
例如,如果X=10110110B(B表示该数是二进制数),那么XL=1011B, XR=0110B, 同时X=1011B*2^4+0110B. x和y的乘积从而可以写为以下形式: 
这里写图片描述 
看上去我们要进行4次实数乘法(乘2的幂相当于左移运算不考虑),实际上,类似上面引言的介绍,只需要进行三次乘法:XLYL,XRYR,(XL + XR)(YL + YR), 因为XLYR + XRYL = (XL + XR)(YL + YR) - XLYL - XRYR 
运行时间改进为O(n^1.59)。

#include<iostream>
#include<cmath>
using namespace std;

#define SIGN(A) ((A>0)?1:-1)//定义一个符号函数表示正负
int multiply(int x, int y,int n)
{
    int sign = SIGN(x)*SIGN(y);
    int XR, XL, YR, YL;
    int P1, P2, P3;
    if (x == 0 || y == 0)
        return 0;
    if (n == 1)
        return x*y;
    else
    {
        //计算X和y的各个部分
        XL = x / pow(10, n / 2);
        XR = x - XL*(pow(10, n / 2));
        YL = y / pow(10, n / 2);
        YR = y - YL*(pow(10, n / 2));
        //分治计算
        P1 = multiply(XL, YL, n-n/2);
        P2 = multiply(XR, YR, n / 2);
        P3 = multiply(XL + XR, YL + YR, n-n/2);
        return sign*(P1*pow(10, 2*floor(n/2)) + (P3 - P1 - P2)*pow(10,n/2) + P2);
    }
}
int main()
{
    printf("请输入两个等长的数字x和y...\n");
    int x, y, n;
    printf("请输入x:\n");
    cin >> x;
    printf("请输入y:\n");
    cin >> y;
    printf("请输入x和y的位数:\n");
    cin >> n;
    printf("---------------------------------------------\n");
    printf("x * y = ");
    cout<<multiply(x, y, n)<<endl;
    printf("非分治算法求得 x * y = ");
    cout << x*y<<endl;
    system("pause");
    return 0;
}

转载

猜你喜欢

转载自www.cnblogs.com/guguchen/p/9296631.html