从大整数乘法的实现到 Karatsuba 快速算法

Karatsuba 快速乘积算法是具有独特合并过程(combine/merge)的分治算法(Karatsuba 是俄罗斯人)。此算法主要是对两个整数进行相乘,并不适用于低位数(如 int 的 32 位的整数)。

1. 大整数乘法的实现

所谓的大整数,就是超出编程语言关于 integral 类型的最大值的那些位数很大的数,也即如果用这些类型进行存储的话,会造成数值溢出(arithmetic overflow),此时可以使用 vector<int> 逐位存储这些数。

执行两数的乘法的方法就是我们小学学乘法时所采用的方式,normalize 负责处理每一位上的进位情况。

void normalize(vector<int>& c){
    for (int i = 0; i < c.size()-1; ++i){
        c[i+1] += c[i]/10;
        c[i] %= 10;
    }
}

vector<int> multiply(const vector<int>& a, const vector<int>& b){
    vector<int> c(a.size()+b.size(), 0);
    for (int i = 0; i < a.size(); ++i){
        for (int j = 0; j < b.size(); ++j){
            c[i+j] += a[i]*b[j];
        }
    }
    normalize(c);
    return c;
}

2. Karatsuba 快速算法

Karatsuba 快速乘积算法首先将两个整数分别一分为二。例如,a 和 b 各位 256 位的整数,那么使用 a1b1 保存前 128 为,而 a0b0 中保存后 128 位。分割后,ab 可写成如下的形式。

{a=a110128+a0b=b110128+b0

所以将 a×b 分割成四项式有如下等式:

a×b==(a1×10128+a0)(b110128+b0)a1b1��z210256+(a0b1+a1b0)��z110128+a0b0��z0

首先根据 z0=a0b0,z2=a1b1 计算 z0,z1,然后利用以下等式:

(a0+a1)(b0+b1)=z0+z1+z2

因此:

  • z2 = a1 * b1
  • z0 = a0 * b0
  • z1 = (a0 + b0)(a1 + b1)-z2-z0
原文地址:https://www.cnblogs.com/mtcnn/p/9423890.html