题解 | #Powerful Calculator#
Powerful Calculator
https://www.nowcoder.com/practice/6bc1dd2ee0ce4257821531719b8d1c83
最勾式的一题,WA了4次才过。没有内置大整数的C++,只能模拟十进制运算。
正整数的加法很好做,只需要处理好进位。
乘法也很好做,去除符号,计算绝对值乘积——只需要写好多位乘一位的乘法,利用先前的加法就可以;然后加上符号即可。
麻烦的是包含负整数的加法,搞得我还以为我忘了小学一年级下册的竖式计算。实际上竖式计算只适合大正数减小正数。所有不同符号的数都要调整减法顺序。
下面是代码:
#include <iostream> #include <string> #include <cmath> #include <algorithm> using namespace std; string software_adder_inner(const string &a_str, const string &b_str, const int a_sign, const int b_sign) { auto a_it = a_str.rbegin(); auto b_it = b_str.rbegin(); string res; int carry = 0; int c = 0; while (true) { if (a_it != a_str.rend() && b_it != b_str.rend()) { const int a = static_cast<int>(*a_it) - static_cast<int>('0'); const int b = static_cast<int>(*b_it) - static_cast<int>('0'); c = a_sign * a + b_sign * b + carry; a_it++; b_it++; } else if (a_it != a_str.rend()) { const int a = static_cast<int>(*a_it) - static_cast<int>('0'); c = a_sign * a + carry; a_it++; } else if (b_it != b_str.rend()) { const int b = static_cast<int>(*b_it) - static_cast<int>('0'); c = b_sign * b + carry; b_it++; } else { break; } if (c < 0) { carry = -1; res.push_back(c + 10 + '0'); } else { carry = c / 10; res.push_back(c % 10 + '0'); } } if (carry != 0) { res.push_back(carry + '0'); } while (*res.rbegin() == '0') { res.pop_back(); } std::reverse(res.begin(), res.end()); return res; } string software_adder(const string &a_str, const string &b_str, const int a_sign, const int b_sign) { if (a_sign == b_sign) { string res = software_adder_inner(a_str, b_str, a_sign, b_sign); if (a_sign < 0) { res = "-" + res; } return res; } else { // substraction string first(a_str), second(b_str); string res; if (a_str.length() < b_str.length()) { std::swap(first, second); res.push_back('-'); } else if (a_str.length() == b_str.length()) { for (int i = 0; i < a_str.length(); i++) { if (a_str[i] < b_str[i]) { std::swap(first, second); res.push_back('-'); break; } else if (a_str[i] > b_str[i]) { break; } } } res += software_adder_inner(first, second, 1, -1); return res; } } string multiplier_helper(const string &a_str, char b_ch) { auto a_iter = a_str.rbegin(); string res; int b = b_ch - '0'; int c = 0; int carry = 0; while (true) { if (a_iter == a_str.rend()) { break; } int a = *a_iter - '0'; c = a * b + carry; carry = c / 10; res.push_back(c % 10 + '0'); a_iter++; } if (carry != 0) { res.push_back(carry + '0'); } reverse(res.begin(), res.end()); return res; } string software_multiplier(const string &a_str, const string &b_str, const int a_sign, const int b_sign) { string res("0"); int indent = 0; auto b_iter = b_str.rbegin(); while (true) { if (b_iter == b_str.rend()) { break; } string tmp = multiplier_helper(a_str, *b_iter); for (int i = 0; i < indent; i++) { tmp.push_back('0'); } res = software_adder(res, tmp, 1, 1); indent += 1; b_iter++; } if (a_sign * b_sign < 0) { res = "-" + res; } return res; } void solution(const string &a, const string &b) { int a_sign = 1, b_sign = 1; string a_, b_; if (a[0] == '-') { a_sign = -1; a_ = a.substr(1); } else { a_ = a; } if (b[0] == '-') { b_sign = -1; b_ = b.substr(1); } else { b_ = b; } string sum_1 = software_adder(a_, b_, a_sign, b_sign); cout << sum_1 << endl; string sum_2 = software_adder(a_, b_, a_sign, -b_sign); cout << sum_2 << endl; string product = software_multiplier(a_, b_, a_sign, b_sign); cout << product << endl; } int main() { string a, b; cin >> a >> b; solution(a, b); }