问题 C++ 反向波兰表示法计算器

Problem C++ Reverse Polish Notation calculator

我对 RPN 有疑问。 我希望程序在按下 ENTER 后完成输入字符,但有些东西不起作用,因为它没有写入 vec。 我尝试解决了这个任务: 应确定以反向波兰表示法记录的表达式的值。表达式将包含以下运算符:+、-、* 和 /(整数除法)和不大于一百万的自然数。结果的类型为 int.

入口 在第一行也是唯一一行中,用逆波兰表示法写的短语。运算符与数字之间用 space 字符分隔。表达式长度少于 1000 个字符。

退出 ONP表达式的结束值。

#include <iostream>
#include <vector>
#include <stack>

using namespace std;

int RPN(vector<string> &notation) {
  stack<int> s;
  for (string str : notation) {
    if (str == "+" or str == "-" or str == "/" or str == "*") {
      int a = s.top();
      s.pop();
      int b = s.top();
      s.pop();

      if (str == "-") {
        s.push(b - a);
        continue;
      }
      if (str == "+") {
        s.push(b + a);
        continue;
      }
      if (str == "/") {
        s.push(b / a);
        continue;
      }
      if (str == "*") {
        s.push(b * a);
        continue;
      }
    } else
      s.push(stoi(str));
  }
  return s.top();
}

int main() {
  vector<string> notation;

  while (true) {
    string sign;
    cin >> sign;
    if (cin.get() != 'n') {
      break;
    } else {
      notation.push_back(sign);
    }
  }
  for (auto i : notation)  // test, print vec
  {
    cout << i << endl;
    ;
  }
  cout << RPN(notation) << endl;
return 0;
}

您的代码没有保持优先级。它像对待乘法一样对待加法。如果那是你想要的,你可以从左到右执行每个操作。

我想你的程序的目标是有一些优先级,例如在加法之前执行乘法。

这是一个保持优先级的简单代码。该代码假定输入始终正确,并且为简单起见不处理括号。

#include <iostream>
#include <vector>
#include <stack>

int getPrecedence(std::string &o)
{
    if (o == "+" || o == "-")
        return 1;

    return 2;
}

int calculate(int a, int b, const std::string &operation)
{
    if (operation == "+")
        return a + b;
    if (operation == "-")
        return a - b;
    if (operation == "*")
        return a * b;
    if (operation == "/")
        return a / b;
    return -1;
}

void performOperation(std::stack<int> &numbers, std::stack<std::string> &operators) {
    int n1 = numbers.top();
    numbers.pop();
    int n2 = numbers.top();
    numbers.pop();
    std::string op = operators.top();
    operators.pop();

    numbers.push(calculate(n2, n1, op));
}

int RPN(std::vector<std::string> &notation) {

    std::stack<int> numbers;
    std::stack<std::string> operators;

    if (notation.empty())
        return 0;

    numbers.push(stoi(notation[0]));

    for (int i = 1; i < notation.size(); i+=2)
    {
        while (!operators.empty() && getPrecedence(operators.top()) >= getPrecedence(notation[i]))
            performOperation(numbers, operators);

        numbers.push(std::stoi(notation[i+1]));
        operators.push(notation[i]);
    }

    while (!operators.empty())
        performOperation(numbers, operators);

    return numbers.top();
}

std::vector<std::string> parse(const std::string& input)
{
    std::vector<std::string> vec;

    std::string current;

    for (char c : input)
    {
        if (isdigit(c))
            current += c;
        else if (c)
        {
            if (!current.empty())
            {
                vec.emplace_back(std::move(current));
                current = "";
            }

            if (c != ' ')
                vec.emplace_back(1, c);
        }
    }

    if (!current.empty())
        vec.push_back(std::move(current));

    return vec;
}

int main() {

    // This program doesn't validate input.
    // It assumes that the input is always correct.

    std::string input;
    std::getline(std::cin, input);
    std::vector<std::string> notation = parse(input);
    std::cout << RPN(notation) << '\n';
}

输入:

1 + 2 + 3 * 3 + 3 / 3 + 5 - 4

输出:

14

为简单起见,我取了程序在获取输入之前将读取的字符串数。


更新:

以上代码假设输入是一个infix表达式。如果输入已经在 RPN 中,代码将是这样的:

#include <iostream>
#include <vector>
#include <stack>

int calculate(int a, int b, const std::string &operation)
{
    if (operation == "+")
        return a + b;
    if (operation == "-")
        return a - b;
    if (operation == "*")
        return a * b;
    if (operation == "/")
        return a / b;
    return -1;
}

bool isOperation(const std::string& op)
{
    return op == "+" || op == "-" || op == "*" || op == "/";
}

int RPN(std::vector<std::string> &notation) {

    std::stack<int> numbers;
    for (const auto& str : notation)
    {
        if (isOperation(str))
        {
            int n2 = numbers.top(); numbers.pop();
            int n1 = numbers.top(); numbers.pop();

            numbers.push(calculate(n1, n2, str));
        }
        else
            numbers.push(std::stoi(str));
    }

    return numbers.top();
}

std::vector<std::string> parse(const std::string& input)
{
    std::vector<std::string> vec;

    std::string current;

    for (char c : input)
    {
        if (isdigit(c))
            current += c;
        else if (c)
        {
            if (!current.empty())
            {
                vec.emplace_back(std::move(current));
                current = "";
            }

            if (c != ' ')
                vec.emplace_back(1, c);
        }
    }

    if (!current.empty())
        vec.push_back(std::move(current));

    return vec;
}

int main() {

    // This program doesn't validate input.
    // It assumes that the input is always correct.

    std::string input;
    std::getline(std::cin, input);
    std::vector<std::string> notation = parse(input);
    std::cout << RPN(notation) << '\n';
}