日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

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

分治算法――Karastsuba算法

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

分治(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


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 久久久在线 | 精品久久免费 | 在线日韩中文字幕 | 男女爱爱网站 | 国产精品一卡 | 国产精品video | 美女搡bbb又爽又猛又黄www | 91精品成人久久 | 性高湖久久久久久久久 | 国产91精品一区二区 | 久草视频观看 | 久久精品黄色 | 特级毛片在线观看 | 日韩视频免费在线观看 | 精品在线免费观看 | 亚洲自拍偷拍网站 | 日韩综合精品 | 日韩和欧美一区二区 | 免费a级毛片在线播放 | 不卡一区二区在线 | 嫩草在线看| 欧美日韩亚洲视频 | 亚洲欧美日韩电影 | 免费一区二区 | 免费一级淫片aaa片毛片a级 | 综合婷婷 | 精品国产31久久久久久 | 青青草久久 | 精品久久久久久久久久久下田 | 亚洲国产日韩在线 | 污污的视频网站 | 中文字幕91 | 精品99在线| 欧美成人a| 久久久久国产精品一区三寸 | 精品国产一区二区三区四区四 | 国产欧美精品在线 | 亚洲精品在线视频观看 | 狼人综合网 | 性欧美xxxx | 成人国产在线视频 |