从大整数乘法的实现到 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 位的整数,那么使用 a1 和 b1 保存前 128 为,而 a0 和 b0 中保存后 128 位。分割后,a 和 b 可写成如下的形式。
所以将 a×b 分割成四项式有如下等式:
首先根据 z0=a0⋅b0,z2=a1⋅b1 计算 z0,z1,然后利用以下等式:
因此:
- z2 = a1 * b1
- z0 = a0 * b0
- z1 = (a0 + b0)(a1 + b1)-z2-z0
从大整数乘法的实现到 Karatsuba 快速算法的更多相关文章
- JAVA版拆分大整数为2幂的和算法
import java.util.ArrayList; import java.util.List; public class StrTest { public static void main(St ...
- 大整数分解质因数(Pollard rho算法)
#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...
- 大整数算法[11] Karatsuba乘法
★ 引子 前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...
- [转]大整数算法[11] Karatsuba乘法
★ 引子 前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...
- 大整数相乘问题总结以及Java实现
最近在跟coursera上斯坦福大学的算法专项课,其中开篇提到了两个整数相乘的问题,其中最简单的方法就是模拟我们小学的整数乘法,可想而知这不是比较好的算法,这门课可以说非常棒,带领我们不断探索更优的算 ...
- 自上而下,逐步揭开PHP解析大整数的面纱
遇到的问题 最近遇到一个PHP大整数的问题,问题代码是这样的 $shopId = 17978812896666957068; var_dump($shopId); 上面的代码输出,会把$shopId转 ...
- 【BZOJ】3751: [NOIP2014]解方程【秦九韶公式】【大整数取模技巧】
3751: [NOIP2014]解方程 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4856 Solved: 983[Submit][Status ...
- Miller-Rabin 素性测试 与 Pollard Rho 大整数分解
\(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要 ...
- 基于Java的大整数运算的实现(加法,减法,乘法)学习笔记
大整数,顾名思义就是特别大的整数. 一台64位的机器最大能表示的数字是2的64次方减一: 18446744073709551615 java语言中所能表示的整数(int)最小为-2147483648 ...
随机推荐
- 紫书 习题 10-21 UVa 1649 (组合数)
C(n, k) = m, 固定k,枚举k 这里用到了组合数的一个性质 当k固定的时候,C(2 * k, k) 最小 C(m, k)最大(对于这道题而言是这样,因为大于m 就最终答案不可能为m了) 所以 ...
- JS实现分页效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- PHP定时执行任务
ignore_user_abort();//关掉浏览器,PHP脚本也可以继续执行. set_time_limit(0);// 通过set_time_limit(0)可以让程序无限制的执行下去 $int ...
- 【转】flex中的labelFunction(combox和dataGrid)
Flex中,对于显示一个字段,只需要指定对应字段属性给labelField即可,当需要上述所需要的功能的时候就得做个转换了,在Flex的基于List的组件都有一个labelFunction方法能很简单 ...
- Struts2的token标签
“token标签的实现原理是在表单中增加一个隐藏域,每次加载该页面时,该隐藏域的值都不相同.而TokenInterceptor拦截器则拦截所有用户请求,如果两次请求时该token对应隐藏域的值相同(前 ...
- Silverlight 应用程序中未处理的错误
Silverlight 开发中遇到个错误: SCRIPT5022: Silverlight 应用程序中未处理的错误 代码: 2108 类别: InitializeError 消息: 无法下载初始屏幕或 ...
- Node.js转化GBK编码 - iconv-lite
node当使用node获取GBK编码的数据时,nodejs仅仅支持utf-8,node没有提供转换编码的原生支持,有倒是有一个模块iconv能干这个事,但须要本地方法,VC++库的支持.国外有个大牛写 ...
- vue -- 动态加载组件 (tap 栏效果)
在 vue 中,实现 Tab 切换主要有三种方式:使用动态组件,使用 vue-router 路由,使用第三方插件. 因为这次完成的功能只是简单切换组件,再则觉得使用路由切换需要改变地址略微麻烦,所以使 ...
- 关于li的排列,我的面试题
来到北京的第二周,收到了单位的面试,一面的时候面试官问了微信钱包里的那个快速入口的排列,我当时在面试官的引导下答的还可以,但是在实际中有很多的方法和各自不同的问题,我来总结下. 1.flex布局,其实 ...
- 6.cocos2d设置定时器
T1LayerAnchorPoint.h #pragma once #include "cocos2d.h" USING_NS_CC; class T1LayerAnchorPoi ...