分治——大整数乘法

来源:互联网 发布:为什么蔬菜不好吃知乎 编辑:程序博客网 时间:2024/06/02 02:07

第一次自己完整写对,多多指教

算法思路:分治。

第一步:经过预处理将两个整数变为长度一样的两个数(短的在前面补0)

第二部:把两个大整数都平分为前后两部分

第三部:按以下公式计算

(实现大数乘法之前实现了大数加减法)

公式:

X=A*10^(n/2)+B

Y=C*10^(n/2)+D

XY=AC*10^n+((A-B)(D-C)+AC+BD)*10^(n/2)+BD

 

#include<iostream>#include<string>#include<algorithm>#include<assert.h>using namespace std;class BigIntegerCalculate {private:static void checkNumber(string numb) {assert(!numb.empty());int len = numb.length();int i = 0;if (len == 1 && numb[0] == '-') assert(false);if (numb[0] == '-') i++;for (; i<len; i++) {if (!(numb[i] >= '0'&&numb[i] <= '9'))assert(false);}}static void wipeOffFZERO(string& numb) {string::iterator it = numb.begin();if (numb[0] == '-') it++;for (; it != numb.end();)if (*it != '0')break;else it = numb.erase(it);if (numb.length() == 0)numb = "0";}static void mulInit(string& numb1, string& numb2) {int len1 = numb1.length();int len2 = numb2.length();if (numb1[0] == '-') len1--;if (numb2[0] == '-') len2--;if (len1 == len2) return;string temp = "";if (len1>len2){if (numb2[0] == '-'){temp.push_back('-');numb2 = numb2.substr(1, string::npos);}for (int i = 0; i<len1 - len2; i++)temp.push_back('0');numb2 = temp + numb2;}else {if (numb1[0] == '-'){temp.push_back('-');numb1 = numb1.substr(1, string::npos);}for (int i = 0; i<len2 - len1; i++)temp.push_back('0');numb1 = temp + numb1;}}static string add(string numb1, string numb2) {wipeOffFZERO(numb1);wipeOffFZERO(numb2);if (numb1[0] == '-'){numb1 = numb1.substr(1, string::npos);return sub(numb2, numb1);}if (numb2[0] == '-'){numb2 = numb2.substr(1, string::npos);return sub(numb1, numb2);}string result = "";int len1 = numb1.length();int len2 = numb2.length();int i = len1 - 1, j = len2 - 1, up = 0;for (; i >= 0 && j >= 0; --i, --j) {int t = numb1[i] - '0' + numb2[j] - '0' + up;result.push_back(t % 10 + '0');up = t / 10;}for (; i >= 0; --i) {int t = numb1[i] - '0' + up;result.push_back(t % 10 + '0');up = t / 10;}for (; j >= 0; --j) {int t = numb2[j] - '0' + up;result.push_back(t % 10 + '0');up = t / 10;}if (up != 0) result.push_back(up + '0');reverse(result.begin(), result.end());return result;}static string sub(string numb1, string numb2) {wipeOffFZERO(numb1);wipeOffFZERO(numb2);if (numb1[0] == '-'){numb1 = numb1.substr(1, string::npos);return '-' + add(numb2, numb1);}if (numb2[0] == '-'){numb2 = numb2.substr(1, string::npos);return add(numb1, numb2);}string result = "";int sign = 1;int len1 = numb1.length();int len2 = numb2.length();string left = numb1, right = numb2;if (len1<len2 || len1 == len2&&numb1.compare(numb2)<0) {left = numb2, right = numb1, sign = -1;int t = len1;len1 = len2;len2 = t;}int i = len1 - 1, j = len2 - 1, down = 0;for (; i >= 0 && j >= 0; --i, --j) {int t = left[i] - right[j] - down;down = 0;while (t<0) {down++;t += 10;};result.push_back(t + '0');}for (; i >= 0; --i) {int t = left[i] - down - '0';down = 0;while (t<0) {down++;t += 10;};result.push_back(t + '0');}for (; j >= 0; --j) {int t = right[i] - down - '0';down = 0;while (t<0) {down++;t += 10;};result.push_back(t + '0');}reverse(result.begin(), result.end());if (sign == -1)result = '-' + result;wipeOffFZERO(result);return result;}static void TZERRO(string& numb) {int len = numb.length();int i = 0;if (numb[0] == '-') i++;for (; i<len; i++)if (numb[i] != '0') return;numb = "0";}static void Transposition(string& numb, int pos) {for (int i = 0; i<pos; i++)numb.push_back('0');}static string mul(string numb1, string numb2) {TZERRO(numb1); TZERRO(numb2);if (numb1 == "0" || numb2 == "0") return "0";mulInit(numb1, numb2);int len = numb1.length();int a = 1, b = 1;if (numb1[0] == '-') { a = -1; len--; numb1 = numb1.substr(1, string::npos); }if (numb2[0] == '-') { b = -1, numb2 = numb2.substr(1, string::npos); }int sign = a*b;string result = "";if (len == 1) {int t = (numb1[0] - '0')*(numb2[0] - '0');result.push_back(t % 10 + '0');if (t / 10 != 0) result = char(t / 10 + '0') + result;}else {string A = numb1.substr(0, len / 2);string B = numb1.substr(len / 2, string::npos);string C = numb2.substr(0, len / 2);string D = numb2.substr(len / 2, string::npos);string AC = mul(A, C);string BD = mul(B, D);string AsubB = sub(A, B);string DsubC = sub(D, C);string M = mul(AsubB, DsubC);M = add(M, AC);M = add(M, BD);Transposition(AC, 2 * (len - len / 2));Transposition(M, len - len / 2);result = add(AC, M);result = add(result, BD);}if (sign == -1)result = '-' + result;return result;}public:static string Add(string numb1, string numb2) {checkNumber(numb1);checkNumber(numb2);return add(numb1, numb2);}static string Sub(string numb1, string numb2) {checkNumber(numb1);checkNumber(numb2);return sub(numb1, numb2);}static string Mul(string numb1, string numb2) {checkNumber(numb1);checkNumber(numb2);return mul(numb1, numb2);}};int main() {string numb1, numb2;cin >> numb1 >> numb2;cout << BigIntegerCalculate::Mul(numb1, numb2) << endl;return 0;}


0 0
原创粉丝点击