题解 | #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);
}

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务