整数相乘的分治算法
来源:互联网 发布:全国网络电视直播 编辑:程序博客网 时间:2024/05/10 16:55
引言
很久很久以前,有人是这样算乘法的:x*y,好经典~
有人是这样算复数乘法的:(a+bi)(c+di)=ac-bd+(bc+ad)i,实数乘法进行了四次,这种普通乘法时间复杂度是O(n^2)。
但是!我们伟大的数学家高斯(Gauss)发现,其实上式可以通过三个实数乘法来完成:ac, bd ,(a+b)(c+d)。
这种算法可以应用到大数相乘之中,当数小的时候这只是很小的改进,但是当数很大的时候,若递归地应用这个小幅改进,则算法的效率得到极其显著的提升!!分治算法介绍
给定两个n位的二进制整数x和y(当然次算法不限定二进制数),作为x乘y的第一步,我们将x和y一分为二,每个数的左半部分和右半部分都是n/2位的二进制整数:
例如,如果X=10110110B(B表示该数是二进制数),那么XL=1011B, XR=0110B, 同时X=1011B*2^4+0110B. x和y的乘积从而可以写为以下形式:
看上去我们要进行4次实数乘法(乘2的幂相当于左移运算不考虑),实际上,类似上面引言的介绍,只需要进行三次乘法:XLYL,XRYR,(XL + XR)(YL + YR), 因为XLYR + XRYL = (XL + XR)(YL + YR) - XLYL - XRYR
运行时间改进为O(n^1.59)。伪代码
下面本人写的代码主要也是参照这个伪代码实现,不同的是加了个符号表示数的正负。函数实现细节(输入x和y,还有它们的位数n,二者等长)
1.计算x*y的正负
2.定义变量
3.判断x和y是否为0,若是0返回0
4.若x和y位数均为1,则直接返回x*y的结果,不必做分治
5.计算x和y的各个部分,XL, XR, YL, YR, 注意考虑n为奇数的情况,则分L比R长一位。
6.计算P1=XLYL,P2=XRYR,P3=(XL + XR)(YL + YR)
7.返回P1x10^(2*floor(n/2))+(P3-P1-P2)x10^(n/2)+P2(此处对应伪代码的最后一行,本人用了十进制)完整代码
#include<iostream>#include<cmath>using namespace std;#define SIGN(A) ((A>0)?1:-1)//定义一个符号函数表示正负int multiply(int x, int y,int n){ int sign = SIGN(x)*SIGN(y); int XR, XL, YR, YL; int P1, P2, P3; if (x == 0 || y == 0) return 0; if (n == 1) return x*y; else { //计算X和y的各个部分 XL = x / pow(10, n / 2); XR = x - XL*(pow(10, n / 2)); YL = y / pow(10, n / 2); YR = y - YL*(pow(10, n / 2)); //分治计算 P1 = multiply(XL, YL, n-n/2); P2 = multiply(XR, YR, n / 2); P3 = multiply(XL + XR, YL + YR, n-n/2); return sign*(P1*pow(10, 2*floor(n/2)) + (P3 - P1 - P2)*pow(10,n/2) + P2); }}int main(){ printf("请输入两个等长的数字x和y...\n"); int x, y, n; printf("请输入x:\n"); cin >> x; printf("请输入y:\n"); cin >> y; printf("请输入x和y的位数:\n"); cin >> n; printf("---------------------------------------------\n"); printf("x * y = "); cout<<multiply(x, y, n)<<endl; printf("非分治算法求得 x * y = "); cout << x*y<<endl; system("pause"); return 0;}
- 结果截图
- 整数相乘的分治算法
- 分治算法之大整数相乘问题
- 分治算法-大整数相乘(JAVA实现)
- 分治算法-最近点对问题、大整数相乘
- 分治法---大整数相乘
- 分治思想 大整数相乘
- 大整数相乘 分治法
- 分治法求整数相乘
- 大整数相乘(分治)
- 分治法的经典问题——大整数相乘
- 分治法的经典问题——大整数相乘
- 分治法的经典问题——大整数相乘
- 分治法的经典问题——大整数相乘
- 分治法的经典问题——大整数相乘
- 分治法的经典问题——大整数相乘
- 一个大整数相乘算法的例子
- 大整数相乘算法
- 大整数相乘算法!
- 阶乘递归函数
- Ubuntu MYSQL环境搭建(apt-get install方式)
- 进程间的通信方式之管道通信
- 移位运算符
- 关于编程的语言的思索 C C++ C# JAVA RUBY PHP
- 整数相乘的分治算法
- zookeeper
- 魅力指数
- 微信公众平台模板消息发送接口文档
- 分布式计算第七周实验:J2EE MVC 编程
- DDS,EasyDarwin部署
- MD5加密----java
- 获取中文请求参数
- 会跳动的图片