遞迴與分治之大整數乘法
大整數乘法
現在我們給出兩個數字1234和4321(這兩個數字並不大,以此為例而已),按照我們做乘法的習慣,我們寫成豎式,用1234分別跟4,3,2,1相乘並對應移位相加得到結果,那麼我們在這個過程中用了幾次乘法呢?是4次?不,其實1234跟4相乘是1,2,3,4分別乘4,也是4次乘法,因此一共我們使用了4*4次乘法。
這僅僅是4位,如果是更多,那麼演算法的複雜度無疑是O(n^2),為了提高效率,降低這種複雜度,我們可以使用分治法。
首先,我們將兩個n位大整數X,Y分開,分為四個n/2位的整數,如下:
例如,X=12345678,分成a=123410^4,b=56781;此時的計算效率如下:
利用我們學過的複雜度分析法,其複雜度如下:
根據master定理,複雜度為O(n^2),並沒有改進。
為了降低複雜度,我們必須用加法代替乘法,因此我們修改一下上面式子的形式:
補充:master定理:
程式碼摘自:https://blog.csdn.net/jeffleo/article/details/53446095
#include<cstdio>
#include<cmath>
using namespace std;
#define SIGN(A) ((A > 0) ? 1 : -1)
int divideConquer(int X, int Y, int n){
int sign = SIGN(X) * SIGN(Y);
int x = abs(X);
int y = abs(Y);
if(x == 0 || y == 0){
return 0;
}else if(n == 1){
return sign * x * y;
}else{
int A = (int) x / pow(10, (int)(n / 2));
int B = x - A * pow(10, n / 2);
int C = (int) y / pow(10, (int)(n / 2));
int D = y - C * pow(10, n / 2);
int AC = divideConquer(A, C, n / 2);
int BD = divideConquer(B, D, n / 2);
int ABDC = divideConquer((A - B), (D - C), n / 2) + AC + BD;
return sign * (AC * pow(10 , n) + ABDC * pow(10, (int)(n / 2)) + BD);
}
}
int main(){
int x, y, n;
scanf("%d%d%d", &x, &y, &n);
printf("x 和 y的乘積為:%d", divideConquer(x, y, n));
}
相關文章
- 20200925—遞迴與分治遞迴
- 分治與遞迴-找k個臨近中位數的數遞迴
- 遞迴與分治演算法練習遞迴演算法
- 大整數乘法
- 遞迴、分治和動態規劃遞迴動態規劃
- 遞迴 & 分治演算法深度理解遞迴演算法
- 歸併排序(C++_分治遞迴)排序C++遞迴
- 高精度整數的乘法
- 計算機演算法設計與分析筆記(二)——遞迴與分治計算機演算法筆記遞迴
- 用遞迴的方法列印出輸入的任意整數遞迴
- PAT-B 1006 換個格式輸出整數【遞迴列印】遞迴
- 遞迴與回溯法遞迴
- 迭代與遞迴--你被遞迴搞暈過嗎?遞迴
- 演算法小專欄:遞迴與尾遞迴演算法遞迴
- 順序表應用7:最大子段和之分治遞迴法遞迴
- 連結串列與遞迴遞迴
- 揹包問題的遞迴與非遞迴演算法遞迴演算法
- 遞迴和尾遞迴遞迴
- 【遞迴】小q的數列遞迴
- hdu1297大數遞迴遞迴
- 遞迴-第X大的數遞迴
- 二叉樹的四種遍歷(遞迴與非遞迴)二叉樹遞迴
- 函式遞迴與生成式函式遞迴
- 快速排序【遞迴】【非遞迴】排序遞迴
- 10-17 c遞迴與遞推初識遞迴
- 【矩陣乘法】【快速冪】遞推矩陣
- Note - CDQ分治/整體二分
- [20180531]函式呼叫與遞迴.txt函式遞迴
- 遍歷二叉樹的遞迴與非遞迴程式碼實現二叉樹遞迴
- 遞迴遞迴
- 用遞迴求出最大公約數和最小公倍數,求補充最小公倍數的遞迴用法遞迴
- 遞迴實現指數型列舉遞迴
- 遞迴函式,可變引數列表遞迴函式
- 二十一、氣泡排序演算法——JAVA實現(遞迴與非遞迴)排序演算法Java遞迴
- 二叉樹——後序遍歷的遞迴與非遞迴演算法二叉樹遞迴演算法
- 什麼是遞迴?遞迴和迴圈的異同遞迴
- 反轉連結串列(遞迴與棧)遞迴
- go 遞迴Go遞迴