[英]Problem C++ Reverse Polish Notation calculator
I have a problem with RPN.我对 RPN 有疑问。 I want the program to finish entering characters after pressing ENTER but something doesn't work because it doesn't write to vec.
我希望程序在按 ENTER 后完成输入字符,但有些东西不起作用,因为它没有写入 vec。 I tried to solve the task: The value of the expression recorded in Reverse Polish Notation should be determined.
我试图解决这个任务:应该确定以逆波兰表示法记录的表达式的值。 The expression will contain the following operators: +, -, * and / (integer division) and natural numbers not greater than one million.
该表达式将包含以下运算符:+、-、* 和 /(整数除法)和不大于一百万的自然数。 The result is in the type int.
结果是 int 类型。
Entrance In the first and only line the phrase written in Reverse Polish Notation.入口 在第一行也是唯一一行,用逆波兰符号书写的短语。 Operators are separated from numbers by a space character.
运算符与数字之间用空格字符分隔。 Expression length is less than 1000 characters.
表达式长度小于 1000 个字符。
Exit The end value of the ONP expression.退出 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;
}
Your code doesn't maintain precedence.您的代码不保持优先级。 It treats addition the same way it treats multiplication.
它处理加法的方式与处理乘法的方式相同。 If that's what you want, you can just perform each operation from left to right.
如果这是您想要的,您可以从左到右执行每个操作。
I suppose the goal of your program is to have some precedence and to perform for example multiplication before addition.我想你的程序的目标是有一些优先级并在加法之前执行例如乘法。
Here is a simple code that maintains precedence.这是一个保持优先级的简单代码。 The code assumes that the input is always correct and do not handle parentheses for simplicity.
该代码假定输入始终正确,并且为简单起见不处理括号。
#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';
}
Input:输入:
1 + 2 + 3 * 3 + 3 / 3 + 5 - 4
Output: Output:
14
For simplicity, I take the number of strings that the program will read before taking the input.为简单起见,我采用程序在输入之前将读取的字符串数。
Update:更新:
The above code assumes that the input is an infix
expression.上面的代码假设输入是一个中
infix
表达式。 If the input is already in the RPN
, the code would be like this:如果输入已经在
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';
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.