问题 C++ 逆波兰表示法计算器
Posted
技术标签:
【中文标题】问题 C++ 逆波兰表示法计算器【英文标题】:Problem C++ Reverse Polish Notation calculator 【发布时间】:2020-05-29 12:34:59 【问题描述】:我对 RPN 有疑问。 我希望程序在按 ENTER 后完成输入字符,但有些东西不起作用,因为它没有写入 vec。 我试图解决这个任务: 应确定以逆波兰表示法记录的表达式的值。该表达式将包含以下运算符:+、-、* 和 /(整数除法)和不大于一百万的自然数。结果是 int 类型。
入口 在第一行也是唯一一行中,用逆波兰符号书写的短语。运算符与数字之间用空格字符分隔。表达式长度小于 1000 个字符。
退出 ONP 表达式的结束值。
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
int RPN(vector<string> ¬ation)
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;
【问题讨论】:
【参考方案1】:您的代码不保持优先级。它处理加法的方式与处理乘法的方式相同。如果这是您想要的,您可以从左到右执行每个操作。
我想你的程序的目标是有一些优先级并在加法之前执行例如乘法。
这是一个保持优先级的简单代码。该代码假定输入始终正确,并且为简单起见不处理括号。
#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> ¬ation)
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> ¬ation)
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';
【讨论】:
@beginnerDevLucas 我已经更新了答案,这样输入就不必分开了。 StackExchange123 - 抱歉,我的错误 - 我误解了您的输入 :) 现在一切正常。谢谢 hmm 我有一个小问题:对于输入 5 6 8 4 * + / 2 + 抛出错误“在抛出一个无效参数后调用终止 // what() stoi 这个程序接受一个中缀表达式并将其转换为后缀表达式(RPN)然后执行计算。您的输入采用后缀表示法。它必须是中缀符号。 @beginnerDevLucas 我已经更新了答案,以便您可以直接输入RPN
以上是关于问题 C++ 逆波兰表示法计算器的主要内容,如果未能解决你的问题,请参考以下文章