zoukankan      html  css  js  c++  java
  • 从大整数乘法的实现到 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
  • 相关阅读:
    论文-Deep Residual Learning for Image Recognition
    网易2017秋招编程题集合-牛客网
    论文-GoogleNet : Going Deeper with Convolutions
    腾讯2016研发工程师编程题-牛客网
    网易2017春招笔试真题编程题集合-牛客网
    剑指offer-把二叉树打印成多行
    剑指offer-翻转单词顺序列
    剑指offer-和为S的连续正数序列
    Java [leetcode 21]Merge Two Sorted Lists
    Java [leetcode 20]Valid Parentheses
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9423891.html
Copyright © 2011-2022 走看看