您的代码不保持优先级。它处理加法的方式与处理乘法的方式相同。如果这是您想要的,您可以从左到右执行每个操作。
我想你的程序的目标是有一些优先级并在加法之前执行例如乘法。
这是一个保持优先级的简单代码。该代码假定输入始终正确,并且为简单起见不处理括号。
#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';
}