分治(Divide and Conquer)算法:问题能够分解为子问题,每一个问题是能够独立的解决的,从子问题的解能够构建原问题。

Divide:中间分、随机分、奇偶分等,将问题分解成独立的子问题

Conquer:子问题的解能够单独解决,从子问题的解构建原问题终于的解

Combine:每一步将子问题产生的解进行合并得到终于的解。合并的复杂度影响终于的算法时间复杂度

Karatsuba算法是在普通乘法算法的基础上进行的提升,使得终于的复杂度从O(n^2)变为了O(n^1.585)。基本思想是将原问题的规模每次减小一般。而且每次解决三个子问题:

X =  Xl*2n/2 + Xr    [Xl 左側n/2位数  Xr 右側n/2位数]
Y =  Yl*2n/2 + Yr    [Yl 左側n/2位数  Yr 右側n/2位数] 
XY = (Xl*2n/2 + Xr)(Yl*2n/2 + Yr)= 2n XlYl + 2n/2(XlYr + XrYl) + XrYr
XY = 2n XlYl + 2n/2 * [(Xl + Xr)(Yl + Yr) - XlYl - XrYr] + XrYr
XY = 22ceil(n/2) XlYl + 2ceil(n/2) * [(Xl + Xr)(Yl + Yr) - XlYl - XrYr] + XrYr

从而得到终于的算法时间复杂度为T(n) = 3T(n/2) + O(n)。得到T(n) = O(n^1.585)。算法的伪代码例如以下:

karatsuba(num1, num2)if (num1 < 10) or (num2 < 10)return num1*num2/* calculates the size of the numbers */m = max(size_base10(num1), size_base10(num2))m2 = m/2/* split the digit sequences about the middle */high1, low1 = split_at(num1, m2)high2, low2 = split_at(num2, m2)/* 3 calls made to numbers approximately half the size */z0 = karatsuba(low1,low2)z1 = karatsuba((low1+high1),(low2+high2))z2 = karatsuba(high1,high2)return (z2*10^(2*m2))+((z1-z2-z0)*10^(m2))+(z0)

以下是使用C++详细实现的过程。假设直接使用整数类型实现。可能会发生溢出,因此使用输入的字符串表示。实际运算的过程将字符串转换为数组进行加、减、乘操作。先看终于的算法实现:

string Multiplicate(string x, string y)
{int len = GetSameSize(x, y);if (len == 0) return 0;if (len == 1) return MultiplyString(x, y);int p = len % 2 == 0 ? len / 2 : len / 2 + 1;string Xh = x.substr(0, len / 2);string Yh = y.substr(0, len / 2);string Xl = x.substr(len / 2);string Yl = y.substr(len / 2);string P1 = Multiplicate(Xh, Yh);string P2 = Multiplicate(Xl, Yl);string P3 = Multiplicate(AddString(Xh, Xl), AddString(Yh, Yl));return AddString(AddString(MultiplyPower(P1, 2 * p), MultiplyPower(MinusString(MinusString(P3, P1), P2), p)), P2);
}

上述就是依照伪代码进行实现,可是使用了字符串的数字运算操作。包含字符串与数组的转换,数组加、减、乘,详细实现例如以下:

void StringToArray(string a, int *arr)
{int n = a.size();for(int i = 0; i < n; i++)arr[n - i - 1] = a.at(i) - '0';
}
void ArrayToString(int *arr, int len, string & a)
{for(int i = 0; i < len; i++)a += '0' + arr[len - i - 1];
}
string DelPreZero(string a)
{int zeros = 0;for (int i = 0; i < a.size(); i++)if (a.at(i) == '0') zeros++;else break;if (zeros == a.size()) return "0";return a.substr(zeros);
}
void MultiplyArray(int a[], int la, int b[], int lb, int *arr)
{int i;for (i = 0; i < la; i++)for (int j = 0; j < lb; j++)arr[i + j] += a[i] * b[j];for (i = 0; i < la + lb - 1; i++){arr[i + 1] += arr[i] / 10;arr[i] = arr[i] % 10;}
}
void AddArray(int a[], int la, int b[], int lb, int *arr)
{int i;int len = la > lb ? lb : la;for (i = 0; i < len; i++)arr[i] += a[i] + b[i];if (la > lb){for (i = lb; i < la; i++)arr[i] = a[i];for (i = 0; i < la; i++){arr[i + 1] += arr[i] / 10;arr[i] = arr[i] % 10;}}else{for (i = la; i < lb; i++)arr[i] = b[i];for (i = 0; i < lb; i++){arr[i + 1] += arr[i] / 10;arr[i] = arr[i] % 10;}}
}
void MinusArray(int a[], int la, int b[], int lb, int *arr) //a must be bigger than b
{int i;for (i = 0; i < lb; i++)arr[i] = a[i] - b[i];for (i = lb; i < la; i++)arr[i] = a[i];for (i = 0; i < la - 1; i++){if (arr[i] < 0){arr[i + 1]--;arr[i] = 10 + arr[i];}}
}
string MultiplyString(string a, string b)
{int m = a.size(), n = b.size();int *arrA = new int[m];int *arrB = new int[n];StringToArray(a, arrA);StringToArray(b, arrB);int *arrC = new int[m + n];for(int i = 0; i < n + m; i++)  arrC[i] = 0;string rst;MultiplyArray(arrA, m, arrB, n, arrC);ArrayToString(arrC, m + n, rst);delete []arrA;delete []arrB;delete []arrC;return DelPreZero(rst);
}string AddString(string a, string b)
{int m = a.size(), n = b.size();int *arrA = new int[m];int *arrB = new int[n];StringToArray(a, arrA);StringToArray(b, arrB);int i, len = m > n ? m : n;int *arrC = new int[len + 1];for(i = 0; i < len + 1; i++) arrC[i] = 0;AddArray(arrA, m, arrB, n, arrC);string rst;ArrayToString(arrC, len + 1, rst);delete []arrA;delete []arrB;delete []arrC;return DelPreZero(rst);
}string MultiplyPower(string a, int len)
{for(int i = 0; i < len; i++)a += '0';return DelPreZero(a);
}string MinusString(string a, string b)
{int m = a.size(), n = b.size();int *arrA = new int[m];int *arrB = new int[n];StringToArray(a, arrA);StringToArray(b, arrB);string rst;int i, len = m > n ?

m : n; int *arrC = new int[len]; for(i = 0; i < len; i++) arrC[i] = 0; MinusArray(arrA, m, arrB, n, arrC); ArrayToString(arrC, len, rst); delete []arrA; delete []arrB; delete []arrC; return DelPreZero(rst); }

主要是涉及到字符串与数组的转换中字符串在数字中是逆序的,进行数组运算时方便,同一时候对于数组间的减法。仅仅支持a 大于b的减法,假设是a 小于b能够用b减去a后再取反就可以。还有就是对数组的动态空间申请后,须要及时释放。

參考:

1.http://www.geeksforgeeks.org/divide-and-conquer-set-2-karatsuba-algorithm-for-fast-multiplication/

2.http://en.wikipedia.org/wiki/Karatsuba_algorithm#Pseudo_Code_Implementation

转载于:https://www.cnblogs.com/mfmdaoyou/p/6708906.html

分治算法——Karastsuba算法相关推荐

  1. python分治算法_Python算法:分治法

    本节主要介绍分治法策略,提到了树形问题的平衡性以及基于分治策略的排序算法 本节的标题写全了就是:divide the problem instance, solve subproblems recur ...

  2. 算法总结---最常用的五大算法(算法题思路)

    算法总结---最常用的五大算法(算法题思路) 一.总结 一句话总结: [明确所求:dijkstra是求点到点的距离,辅助数组就是源点到目标点的数组] [最简实例分析:比如思考dijkstra:假设先只 ...

  3. 经典常用算法/常用算法思维---附伪代码以及实现

    本篇文章旨在分享一些常用算法的伪代码以及部分算法的具体实现,后面也会更新我在刷算法题中学到的或者从别的地方看到的经典算法思维 本博客并不提供算法说明,算法证明,算法分析,算法测试等内容,只提供算法的伪 ...

  4. 算法与数据结构_数据结构与算法专题--算法基本概念

    很多开发者都知道"程序=数据结构+算法"这个著名的公式,并不真正明白算法的定义或概念.究竟什么是算法呢?从字面意义上理解,算法即用于计算的方法,通过这种方法可以达到预期的计算结果. ...

  5. 递归算法 流程图_什么是算法?如何学习算法?算法入门

    转自:http://www.cnblogs.com/jiangwz/p/7765694.html 算法 什么是算法? 有一个很著名的公式 "程序=数据结构+算法". 曾经跟朋友吃饭 ...

  6. 递归算法 流程图_什么是算法?如何学习算法?算法入门的学习路径

    什么是算法? 有一个很著名的公式 "程序=数据结构+算法". 曾经跟朋友吃饭的时候我问他什么是算法,他说算法嘛,就是一套方法,需要的时候拿过来,套用就可以,我吐槽他,他说的是小学数 ...

  7. 常用算法的算法思想以及基本特征

    算法思想 递归 递归并不是简单的自己调用自己,也不是简单的交互调用.递归在于把问题分解成规模更小.具有与原来问题相同解法的问题,如二分查找以及求集合的子集问题.这些都是不断的把问题规模变小,新问题与原 ...

  8. 【算法】算法设计技术

    算法设计技巧 文章目录 算法设计技巧 贪心算法(贪婪算法) 多处理器情况 活动选择问题 活动选择问题(加权) 递归解 独立集问题 树上的独立集问题 装箱问题 联机和脱机 近似在线装箱算法 脱机算法 分 ...

  9. 神经网络最短路径算法,最短路径算法的原理

    节约里程法求解最短路问题 你只要记住2点之间直线最短.节约里程法是用来解决运输车辆数目不确定的问题的最有名的启发式算法.1.节约里程法优化过程分为并行方式和串行方式两种. 核心思想是依次将运输问题中的 ...

最新文章

  1. mount --bind
  2. 不安装Oracle使用cx_Oracle
  3. Python 中 zip() 函数的用法
  4. C语言字符数组与字符串的使用及加结束符‘\0‘的问题
  5. ubuntu10.4安装交叉编译器arm-none-linux-gnueabi-gcc
  6. apache +php + mysql_apache+php+mysql
  7. P4211 [LNOI2014]LCA(离线 + 在线 做法)
  8. 巧用枚举CommandBehavior关闭SqlDataReader联接数据库时的conn.open状态
  9. JSF和Facelets的lifecircle
  10. JSP指示元素%@ % 与指示类型
  11. hello March
  12. java 接收前台富文本_前后端分离ueditor富文本编辑器的使用-Java版本
  13. 第19集 轮廓的提取
  14. iphone编辑过的录音怎么还原_ios录音误剪怎么恢复
  15. AD9的PCB技巧——封装的更新
  16. ws2812 c语言程序,STC15单片机驱动WS2812B七彩LED(汇编混合编程)
  17. TwinCAT 软件安装级别的简要介绍,倍福FTP
  18. 浏览器播放语音SpeechSynthesisUtterance
  19. map-box地图点击图标高亮事件
  20. python实现直播功能rtmo_30 行 Python 代码实现 Twitch 主播上线实时通知

热门文章

  1. 全国地铁数据爬取-python
  2. java获取u盘_读取U盘信息
  3. html5 中心点旋转,html5 canvas围绕中心点旋转
  4. iphone4s拒接电话
  5. 如何安装xampp(linux版)
  6. 图网络embeding transE及node2vec方法
  7. 【飞行器】模拟四旋翼飞行器飞行含Matlab源码
  8. 怎么把打开方式还原计算机程序,怎么把一个DAT用打开方式变成其他格式再还原成DAT文件...
  9. matlab fmu,导入 FMU - MATLAB Simulink - MathWorks 中国
  10. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(3)- Serial ISP模式(blhost)