分治——大整数乘法
来源:互联网 发布:为什么蔬菜不好吃知乎 编辑:程序博客网 时间: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
- 大整数乘法——分治法
- 分治——大整数乘法
- 分治——大整数乘法
- 大整数分治乘法
- 大整数乘法---分治
- 大整数乘法-分治
- 分治-大整数乘法
- 大整数乘法(分治法)
- 分治算法-大整数乘法
- 大整数乘法 ------分治法
- 分治算法--大整数乘法
- 递归分治-大整数乘法
- 【分治算法】大整数乘法
- 算法06:大整数乘法分治算法——分治法Part2
- 分治法大整数乘法和普通大整数乘法
- 分治算法——大整数乘法(multiplication of large integers)
- 分治法解决大整数乘法问题
- 分治法 --- 大整数的乘法
- Kmeans及其改进算法的Matlab解析与实现
- Spring装配Bean的3种方式解析
- Android中Http的Get与Post
- C# 窗体动态显示 Label文字
- 程序员必会算法系列--基本排序7个
- 分治——大整数乘法
- java 开发环境搭建配置笔记
- getContextPath、getServletPath、getRequestURI的区别
- Publish Subscribe Channel 订阅
- 2-5 分数化小数
- QT系列:生成UUID
- hdu 1069 Monkey and Banana
- 2.6数组运算和矩阵运算
- Android 编程技巧之 ----- 一次追查 DeadObjectException 的总结