随手记——大整数运算模板(进化史)
大整数相加、相乘
2019年2月23日09:46:21
基本上没有空间浪费。关键是思路清晰,实现起来方便,字符串倒过来放到vector里(倒过来 方便进位运算),然后做完运算再逆序回来。
关于乘法运算,本来是每乘好一位,进位处理一次,其实可以最后统一进位。(统一进位的话最大范围:INT_MAX / 81,10^9位,完全够用了)。
#include <iostream> #include <algorithm> #include <string> #include <vector> using namespace std; void carry(vector<int>&a) { for (int i = 0; i < a.size(); i++) { if (i != a.size() - 1) a[i + 1] += a[i] / 10; else if (a[i] >= 10)a.push_back(a[i] / 10); a[i] %= 10; } while (a[a.size() - 1] == 0)a.pop_back(); reverse(a.begin(), a.end()); } void add(vector<int>&a, vector<int>b) { for (int i = 0; i < b.size(); i++) { a[i] += b[i]; } carry(a); } void multi(vector<int>&a,vector<int>b) { //乘法运算,开两个数位数之和,确保不会超范围 vector<int>t(a.size() + b.size()); int k = 0; for (int i = 0; i < b.size(); i++) { for (int j = 0; j < a.size(); j++) { t[j + k] += (a[j] * b[i]); } k++; } carry(t); a = t; } void StringToArray(string s1, string s2, vector<int>&a, vector<int>&b) { if (s1.length() < s2.length())swap(s1, s2); for (int i = s1.length() - 1; i >= 0; i--) { a.push_back(s1[i] - '0'); } for (int i = s2.length() - 1; i >= 0; i--) { b.push_back(s2[i] - '0'); } } int main() { string s1 = "13234321324"; string s2 = "232345444"; long long l1 = 13234321324; long long l2 = 232345444; vector<int>a, b; cout << l1 * l2 << endl; StringToArray(s1, s2,a,b); multi(a, b); for (int i = 0; i < a.size(); i++) { cout << a[i]; } cout << endl; return 0; }
#include <iostream> #include <algorithm> #include <string> using namespace std; int a[100], b[100]; int len1; void carry() { int i = 0; for (int i = 0; i < len1; i++) { if (a[i] >= 10) { if (i == len1 - 1)len1++; a[i + 1] += a[i] / 10; a[i] %= 10; } } } void add() { for (int i = 0; i < len1; i++) { a[i] += b[i]; } carry(); } int main() { string s1="24354673235467", s2="25372472735767"; long long l1= 24354673235467, l2= 25372472735767; //cin >> s1 >> s2; if (s2.length() > s1.length())swap(s1, s2); len1 = s1.length(); for (int i = s1.length() - 1; i >= 0; i--) { a[s1.length() - i - 1] = s1[i] - '0'; } for (int i = s2.length() - 1; i >= 0; i--) { b[s2.length() - i - 1] = s2[i] - '0'; } add(); for (int i = len1 - 1; i >= 0; i--) { cout << a[i]; } cout << endl; cout << l1 + l2 << endl; return 0; }
大整数相减
2019年2月27日15:23:38,只能做正数相减运算
https://code.mi.com/problem/list/view?id=3
#include <iostream> #include <string> #include <vector> using namespace std; bool flag = false; void initialize(vector<int>&a, vector<int>&b) { flag = false; if (!a.empty())a.clear(); if (!b.empty())b.clear(); } void stringToArray(string s1, string s2, vector<int>&a, vector<int>&b) { for (int i = s1.length() - 1; i >= 0; i--) { a.push_back(s1[i] - '0'); } for (int i = s2.length() - 1; i >= 0; i--) { b.push_back(s2[i] - '0'); } } void carry(vector<int>&a) { //处理,11-12,这种情况 while (a.size() > 1 && a[a.size() - 1] == 0)a.pop_back(); for (int i = 0; i < a.size(); i++) { if (i != a.size() - 1 && a[i] < 0) { a[i] += 10; a[i + 1] -= 1; } } } void sub(vector<int>&a, vector<int>b) { if (a.size() < b.size()) { flag = true; swap(a, b); } for (int i = 0; i < b.size(); i++) { a[i] -= b[i]; } carry(a); } int main() { vector<int>a, b; string s; while (cin >> s) { initialize(a, b); stringToArray(s.substr(0, s.find('-')), s.substr(s.find('-') + 1), a, b); sub(a, b); if (flag)a[a.size() - 1] = -a[a.size() - 1]; for (int i = a.size() - 1; i >= 0; i--) { cout << a[i]; } cout << endl; } return 0; }
大数除小数
#include <iostream> #include <time.h> #include <string> #include <vector> using namespace std; void divide(vector<int>&a, int b) { vector<int>v; int i, k, t = 0, s = 0; bool flag = true; for (i = 0, k = 0; i < a.size(); i++) { t = s * 10 + a[i]; if (t / b > 0 || t == 0) { v.push_back(t / b); s = t % b; flag = false; } else { s = t; if (!flag) v.push_back(0); } } if (v.size() == 0)v.push_back(0); a = v; } void f(vector<int>&a,long long l) { while (l) { a.push_back(l % 10); l /= 10; } reverse(a.begin(), a.end()); } int main() { srand(time(0)); for (int i = 0; i < 100000; i++) { vector<int>a; long long l1, l2, ans = 0; l1 = rand() % 132456742353 + 1; l2 = rand() % 132456742353 + 1; //cin >> l1 >> l2; f(a, l1); divide(a, l2); for (int i = 0; i < a.size(); i++) { ans = ans * 10 + a[i]; } if (ans != (l1 / l2)) { cout << "fuck" << endl; } } return 0; }