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. @MapperScan 和 @ComponentScan 区别

    1.首先@MapperScan和@ComponentScan都是扫描包 2.@ComponentScan是组件扫描注解,用来扫描@Controller  @Service  @Repository这类 ...

  2. HOJ——T 2275 Number sequence

    http://acm.hit.edu.cn/hoj/problem/view?id=2275 Source : SCU Programming Contest 2006 Final   Time li ...

  3. C# 之 继承

    继承     继承是OOP最重要的特性之中的一个.不论什么类都能够从还有一个类中继承,这就是说,这个类拥有它继承的类的全部成员. 在OOP中,被继承的类称为父类. 在C#中的对象仅能直接派生于一个基类 ...

  4. 对string的一些扩展函数

    对string作了一些扩展,包含string转化为int.string转化为double.string转化为bool.打印系统当前时间.但没有解决数据溢出的问题,请大神帮忙解决! //头文件 /*pa ...

  5. linux 进程等待 wait 、 waitpid

    waitpid() 与 wait() 功能相似,都是用户主进程等待子进程结束或中断. 可用于进程之间的同步 wait 函数原型 pid_t wait(int *status); 函数说明 wait() ...

  6. Python下opencv使用笔记(一)(图像简单读取、显示与储存)

    写在之前 从去年開始关注python这个软件,途中间间断断看与学过一些关于python的东西.感觉python确实是一个简单优美.easy上手的脚本编程语言,众多的第三方库使得python异常的强大. ...

  7. jquery13 attr() prop() val() addClass()等 : 对元素属性的操作

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  8. Android 学习笔记之Bitmap位图的缩放

    位图的缩放也可以借助Matrix或者Canvas来实现. 通过postScale(0.5f, 0.3f)方法设置旋转角度,然后用createBitmap方法创建一个经过缩放处理的Bitmap对象,最后 ...

  9. Codefroces Educational Round 26 837 B. Flag of Berland

    B. Flag of Berland time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  10. DG的数据保护模式

    DG的数据保护模式 数据保护膜有三种: – Maximum protection – Maximum availability – Maximum performance Maximum protec ...