题解 | #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);
}
查看30道真题和解析