今天刷了高精度专题,本来准备写一个高精度类,然后直接套模版,后来发现根据每题的要求分开写高精度反而效率高。
主要涉及了高精度加法、乘法、除法、取余(其中后两项为高精度和低精度进行运算)。
终于打过一遍高精度除以低精度了,高精度专题也算圆满了。
高精度加法,水题。
#include <iostream> #include <string> #include <memory.h> using namespace std; const int MAX = 10240; int nLen; int pData[MAX]; int main() { nLen = 1; memset(pData, 0, sizeof(pData)); string x; while(cin >> x) { if(x != "0") { while(x[0] == ‘0‘) { x = x.substr(1, x.length() - 1); } nLen = max(nLen, (int)x.length()); for(int i = 1; i <= x.length(); i++) { pData[i] += x[x.length() - i] - ‘0‘; pData[i + 1] += pData[i] / 10; pData[i] %= 10; } while(pData[nLen + 1]) { nLen++; } } else { for(int i = nLen; i >= 1; i--) { cout << pData[i]; } cout << endl; nLen = 1; memset(pData, 0, sizeof(pData)); } } return 0; }
高精度乘法,要注意的是某一个乘数为0的情况,要特判一下。
#include <iostream> #include <string> #include <memory.h> using namespace std; const int MAX = 10240; int nLen; int pData[MAX]; int main() { string x, y; while(cin >> x >> y) { if(x.length() < y.length()) { swap(x, y); } nLen = x.length() + y.length(); memset(pData, 0, sizeof(pData)); for(int i = 1; i <= y.length(); i++) { for(int j = 1; j <= x.length(); j++) { pData[i + j - 1] += (x[x.length() - j] - ‘0‘) * (y[y.length() - i] - ‘0‘); pData[i + j] += pData[i + j - 1] / 10; pData[i + j - 1] %= 10; } } while(nLen && !pData[nLen]) { nLen--; } if(nLen == 0) { nLen = 1; } for(int i = nLen; i >= 1; i--) { cout << pData[i]; } cout << endl; } return 0; }
判断加数、乘数以及结果是否在int范围内,一开始把结果都算出来再比较。后来查了资料发现可以直接用double过,其中使用到了atof这个命令。
#include <iostream> #include <string> #include <stdlib.h> using namespace std; const int MAX_INT = 2147483647; int main() { char dwOpt; string x, y; while(cin >> x >> dwOpt >> y) { cout << x << " " << dwOpt << " " << y << endl; double a, b; a = atof(x.c_str()); b = atof(y.c_str()); if(a > MAX_INT) { cout << "first number too big" << endl; } if(b > MAX_INT) { cout << "second number too big" << endl; } if(dwOpt == ‘+‘ && a + b > MAX_INT) { cout << "result too big" << endl; } if(dwOpt == ‘*‘ && a * b > MAX_INT) { cout << "result too big" << endl; } } }
带有小数的乘方问题。
先确定小数点的位数,然后去掉小数点,进行高精度乘方运算,最后加上小数点即可。
#include <iostream> #include <string> #include <memory.h> using namespace std; const int MAX = 10240; int nLen, nDot; int pData[MAX]; string Solve(string x, string y); int main() { string x; int y; while(cin >> x >> y) { while(x[x.length() - 1] == ‘0‘) { x = x.substr(0, x.length() - 1); } nDot = x.length() - x.find(‘.‘) - 1; nDot *= y; x = x.substr(0, x.find(‘.‘)) + x.substr(x.find(‘.‘) + 1, x.length() - x.find(‘.‘) - 1); string z = "1"; for(int i = 1; i <= y; i++) { z = Solve(z, x); } if(z.length() <= nDot) { cout << "."; for(int i = z.length(); i < nDot; i++) { cout << "0"; } cout << z << endl; } else { for(int i = 0; i < z.length() - nDot; i++) { cout << z[i]; } cout << "."; for(int i = z.length() - nDot; i < z.length(); i++) { cout << z[i]; } cout << endl; } } return 0; } string Solve(string x, string y) { if(x.length() < y.length()) { swap(x, y); } nLen = x.length() + y.length(); memset(pData, 0, sizeof(pData)); for(int i = 1; i <= y.length(); i++) { for(int j = 1; j <= x.length(); j++) { pData[i + j - 1] += (x[x.length() - j] - ‘0‘) * (y[y.length() - i] - ‘0‘); pData[i + j] += pData[i + j - 1] / 10; pData[i + j - 1] %= 10; } } while(nLen && !pData[nLen]) { nLen--; } if(nLen == 0) { nLen = 1; } string z = ""; for(int i = 1; i <= nLen; i++) { z = (char)(pData[i] + ‘0‘) + z; } return z; }
高精度除以低精度以及取模运算。在网上搜了资料,终于学会了。但是要注意0 % X的情况。
另外想说的是非常喜欢这道题目的标题“If We Were A Child Again”,勾起了多少回忆。
#include <iostream> #include <memory.h> using namespace std; const int MAX = 10240; int nLen; int pData[MAX], pAns[MAX]; string Solve(string x, long long y, char dwOpt); int main() { char dwOpt; string x; long long y; while(cin >> x >> dwOpt >> y) { cout << Solve(x, y, dwOpt) << endl; } return 0; } string Solve(string x, long long y, char dwOpt) { memset(pData, 0, sizeof(pData)); memset(pAns, 0, sizeof(pAns)); nLen = x.length(); for(int i = 1; i <= x.length(); i++) { pData[i] = x[x.length() - i] - ‘0‘; } long long d = 0; for(int i = nLen; i >= 1; i--) { d = d * 10 + pData[i]; pAns[i] = d / y; d %= y; } while(nLen && pAns[nLen] == 0) { nLen--; } if(nLen == 0) { nLen = 1; } string z = ""; if(dwOpt == ‘/‘) { for(int i = 1; i <= nLen; i++) { z = (char)(pAns[i] + ‘0‘) + z; } } else { while(d) { z = (char)(d % 10 + ‘0‘) + z; d /= 10; } if(z == "") { z = "0"; } } return z; }
今天由于题目相对比较少,所以做的比较快。接下来一个专题应该是排序和检索。
原文:http://www.cnblogs.com/Ivy-End/p/4279973.html