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 位的整数,那么使用 a1 和 b1 保存前 128 为,而 a0 和 b0 中保存后 128 位。分割后,a 和 b 可写成如下的形式。

{a=a1⋅10128+a0b=b1⋅10128+b0

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

a×b==(a1×10128+a0)(b110128+b0)a1b1z210256+(a0b1+a1b0)z110128+a0b0z0

首先根据 z0=a0⋅b0,z2=a1⋅b1 计算 z0,z1,然后利用以下等式:

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

因此:

  • z2 = a1 * b1
  • z0 = a0 * b0
  • z1 = (a0 + b0)(a1 + b1)-z2-z0

从大整数乘法的实现到 Karatsuba 快速算法的更多相关文章

  1. JAVA版拆分大整数为2幂的和算法

    import java.util.ArrayList; import java.util.List; public class StrTest { public static void main(St ...

  2. 大整数分解质因数(Pollard rho算法)

    #include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...

  3. 大整数算法[11] Karatsuba乘法

    ★ 引子         前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...

  4. [转]大整数算法[11] Karatsuba乘法

    ★ 引子         前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...

  5. 大整数相乘问题总结以及Java实现

    最近在跟coursera上斯坦福大学的算法专项课,其中开篇提到了两个整数相乘的问题,其中最简单的方法就是模拟我们小学的整数乘法,可想而知这不是比较好的算法,这门课可以说非常棒,带领我们不断探索更优的算 ...

  6. 自上而下,逐步揭开PHP解析大整数的面纱

    遇到的问题 最近遇到一个PHP大整数的问题,问题代码是这样的 $shopId = 17978812896666957068; var_dump($shopId); 上面的代码输出,会把$shopId转 ...

  7. 【BZOJ】3751: [NOIP2014]解方程【秦九韶公式】【大整数取模技巧】

    3751: [NOIP2014]解方程 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4856  Solved: 983[Submit][Status ...

  8. Miller-Rabin 素性测试 与 Pollard Rho 大整数分解

    \(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要 ...

  9. 基于Java的大整数运算的实现(加法,减法,乘法)学习笔记

    大整数,顾名思义就是特别大的整数. 一台64位的机器最大能表示的数字是2的64次方减一: 18446744073709551615 java语言中所能表示的整数(int)最小为-2147483648 ...

随机推荐

  1. oracle 正序 逆序 排序查询

    正序:从小到大 order by t.id asc 逆序:从大到小 order by t.id desc

  2. Maven学习总结(12)——eclipse中构建多模块maven项目

    摘要:本文要用Maven来构建一个多模块的web项目 项目结构如下: system-parent      |----pom.xml      |----system-domain          ...

  3. Uva 10081 Tight words (概率DP)

    Time limit: 3.000 seconds Given is an alphabet {0, 1, ... , k}, 0 <= k <= 9 . We say that a wo ...

  4. 什么是PV和UV?

    技术角度 1个PV是指从浏览器发出一个对网络server的Request,网络server接到Request之后.会開始把该Request相应的一个Page(Page就是一个网页)发送到client的 ...

  5. HDU 1429 胜利大逃亡(续)(bfs)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  6. tomcat指定配置文件路径方法

    1.在catalina.sh 中设置JAVA_OPTS,例如: JAVA_OPTS='-server -Xms1024m -Xmx1024m -XX:NewSize=128m -XX:MaxPermS ...

  7. Linux系统存储交换机日志

    Linux系统存储交换机日志     日志记录是为系统设备在运行过程中报告其运行情况而设的, 为了保证系统正常运行, 解决每一天可能遇到的各种各样的问题, 网络管理员必须认真地读取日志记录.目前公司系 ...

  8. Kali的源得数字验证问题

    装上之后第一件事就是执行apt-get update && apt-get upgrade,结果却出现了这样的错误 我添加的是中科大的更新源,在浏览器中是可以正常打开的: deb ht ...

  9. 【hdu 4289】Control

    [Link]:http://acm.hdu.edu.cn/showproblem.php?pid=4289 [Description] 给出一个又n个点,m条边组成的无向图.给出两个点s,t.对于图中 ...

  10. [Javascript] Classify JSON text data with machine learning in Natural

    In this lesson, we will learn how to train a Naive Bayes classifier and a Logistic Regression classi ...