多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > 分治算法――Karastsuba算法

分治算法――Karastsuba算法

來源:程序員人生   發布時間:2014-11-13 08:18:15 閱讀次數:3211次

分治(Divide and Conquer)算法:問題可以分解為子問題,每一個問題是可以獨立的解決的,從子問題的解可以構建原問題。

Divide:中間分、隨機分、奇偶分等,將問題分解成獨立的子問題

Conquer:子問題的解可以單獨解決,從子問題的解構建原問題終究的解

Combine:每步將子問題產生的解進行合并得到終究的解,合并的復雜度影響終究的算法時間復雜度

Karatsuba算法是在普通乘法算法的基礎上進行的提升,使得終究的復雜度從O(n^2)變成了O(n^1.585),基本思想是將原問題的范圍每次減小1般,并且每次解決3個子問題:

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⑵-karatsuba-algorithm-for-fast-multiplication/

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


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: a级片毛片 | 国产精品久久久久无码av | 多人伦交性欧美精品欧 | 性做久久久久久久免费看 | 91精品久久久久亚洲国产 | 日本一区二区三区不卡在线视频 | 亚洲成人在线免费观看 | 婷婷夜夜躁天天躁人人躁 | 伊人伊人影院 | 亚洲欧美另类专区 | 日韩高清一区二区三区五区七区 | 性猛交╳xxx乱大交 性猛交xxxxx按摩 | 亚洲色大成网站www 亚洲色大成网站www久久九九 | 欧美一区二区在线播放 | 国产一区二区福利久久 | 日本不卡视频一区二区三区 | 中文字幕亚洲专区 | 国产成人久久精品推最新 | 羞羞网站免费 | 欧美日韩国产精品 | 99爱免费观看视频在线 | 一级a毛片免费 | 国产乱码精品一区二区三区卡 | 亚洲视频在线观看免费视频 | 国产欧美一区二区三区在线看 | 天天干夜夜骑 | 视频一区 国产 | 欧美另类小说乱小说 | 99re热久久精品这里都是精品 | 免费观看黄色的网站 | 国产精品成人免费福利 | 男女啪啪成人免费网站 | 亚洲成av人片在线观看 | 能在线观看的一区二区三区 | 中文字幕乱偷乱码亚洲 | 亚洲一区二区三区四区五区六区 | 欧美日本韩国一区二区 | 激情影院在线视频永久观看 | 91成人爽a毛片一区二区 | 亚洲精品在线播放 | 亚洲欧美色一区二区三区 |