1. 程式人生 > >分治法解決大整數乘法

分治法解決大整數乘法

大整數乘法

最近學習了演算法設計與分析課程,留了一道大整數乘法的問題,使用了分治法思想,和我之前在學校演算法俱樂部時所寫的原理不太一樣。於是分享出來

#include "pch.h"
//大整數乘法

#include<iostream>
#include <sstream>
#include<ctime>
#include<cmath>
using namespace std;

//在字串後面新增n個0,起到移位作用
void mov(string &x, int n)
{
	x.append(n, '0');
}
//兩多項式結果求和
string sum
(string a, string b) { stringstream ss; string ans;//結果的逆序 int la = a.length(); int lb = b.length(); int c = 0; int min = la < lb ? la : lb; for (int i = 0; i < min; i++) { int num = a[a.length() - 1 - i] + b[b.length() - 1 - i] - 2 * '0'; int num_temp = (c + num) % 10; ss << num_temp;
ans.append(ss.str()); ss.str(""); c = (c + num) / 10; } if (la > lb) { int k = min; while (k < la) { int num_temp = (a[la - 1 - k] - '0' + c) % 10; ss << num_temp; ans.append(ss.str()); ss.str(""); c = (a[k] - '0' + c) / 10; k++; } } else if (la < lb) {
int k = min; while (k < lb) { int num_temp = (b[lb - 1 - k] - '0' + c) % 10; ss << num_temp; ans.append(ss.str()); ss.str(""); c = (b[k] - '0' + c) / 10; k++; } } else {} if (c != 0) { ss << c; ans.append(ss.str()); } //除去多的0 if (count(ans.begin(), ans.end(), '0') == ans.length()) { ans = "0"; } //翻轉字串來獲得正確順序 for (int i = 0; i < ans.length() / 2; i++) { char temp = ans[i]; ans[i] = ans[ans.length() - 1 - i]; ans[ans.length() - 1 - i] = temp; } return ans; } string mul(string a, int y1, string b, int y2) { //如果兩項都只有一位 if (a.length() == 1 && b.length() == 1) { stringstream ss; ss << (a[0] - '0')*(b[0] - '0'); return ss.str(); } int k1 = 0, k2 = 0; string a1, a2, b1, b2; //如果有一個為一位 if (a.length() == 1 || b.length() == 1) { if (a.length() == 1) { k1 = 0; a1 = a; a2 = "0"; k2 = b.length() / 2 + b.length() % 2; b1 = b.substr(0, b.length() / 2); b2 = b.substr(b.length() / 2); } if (b.length() == 1) { k2 = 0; b1 = b; b2 = "0"; k1 = a.length() / 2 + a.length() % 2; a1 = a.substr(0, a.length() / 2); a2 = a.substr(a.length() / 2); } } else { k1 = a.length() / 2 + a.length() % 2; a1 = a.substr(0, a.length() / 2); a2 = a.substr(a.length() / 2); k2 = b.length() / 2 + b.length() % 2; b1 = b.substr(0, b.length() / 2); b2 = b.substr(b.length() / 2 ); } //多項式 string x1 = mul(a1, k1, b1, k2); string x2 = mul(a1, k1, b2, 0); string x3 = mul(a2, 0, b1, k2); string x4 = mul(a2, 0, b2, 0); //對多項式移位 mov(x1, k1 + k2); mov(x2, k1); mov(x3, k2); return sum(sum(x1, x2), sum(x3, x4)); } int main() { string a, b; cin >> a >> b; string ans; ans = mul(a, 0, b, 0); cout << ans << endl; return 0; }

所有的因子都用string型別表示,位數限制在於string型別的位數最大值也就是大概2G,也就是說能夠輕鬆做上萬位的乘法。不過想當然的,速度不會和你做int範圍內乘法相提並論。
這個程式經過我的一些測試,如果讀者發現一些不正確的用例,請勘誤。
僅做參考,請不要cv交作業,學習程式設計不是僅僅從看懂程式開始的。