逆波兰表达式(Reverse Polish Notation, RPN),也称为后缀表达式,是一种没有括号、运算符位于操作数之后的数学表达式表示法。逆波兰表达式的主要优点是它不需要使用括号来指示运算顺序,可以直接通过一个栈来解析和计算。
一、使用栈实现逆波兰表达式计算
#include <stack>
#include <string>
#include <iostream>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param tokens string字符串vector
* @return int整型
*/
int evalRPN(vector<string>& tokens) {
using namespace std;
// write code here
int l=0;
int r=0;
stack<int> stac;
for (string str:tokens) {
if ((str!="+" )&& (str!="-") && (str!="*") && (str!="/")) {
stac.push(stoi(str) );
}else {
int r = stac.top();
stac.pop();
int l = stac.top();
stac.pop();
if (str=="+") {
stac.push(l+r);
}else if(str=="-"){
stac.push(l-r);
}else if(str=="*"){
stac.push(l*r);
}else if(str=="/"){
stac.push(l/r);
}
}
}
return stac.top();
}
};
二、扩展-中缀表达式转化成逆波兰表达式
中缀表达式(如 3 + 4 * 5
)到逆波兰表达式(如 3 4 5 * +
)的转换通常需要两个栈:一个用于存放操作数,另一个用于存放运算符。下面是具体的步骤:
- 初始化两个栈:一个用于操作数(这里不需要),另一个用于运算符。
- 从左到右扫描中缀表达式。
- 遇到数字时,直接输出。
- 遇到运算符时,比较栈顶运算符的优先级与当前运算符的优先级:
- 如果当前运算符的优先级高于栈顶运算符,则将当前运算符压入栈中。
- 否则,弹出栈顶运算符并输出,重复此过程直到当前运算符的优先级高于栈顶运算符,然后将当前运算符压入栈中。
- 遇到左括号时,直接压入栈中。
- 遇到右括号时,弹出栈顶运算符并输出,直到遇到对应的左括号为止,然后将这对括号丢弃。
- 表达式结束后,依次弹出栈中的所有运算符并输出。
#include <iostream> #include <stack> #include <vector> #include <unordered_map> using namespace std; vector<string> infixToPostfix(const vector<string>& tokens) { stack<string> operators; vector<string> output; unordered_map<string, int> precedence = {{"+", 1}, {"-", 1}, {"*", 2}, {"/", 2}}; for (const auto& token : tokens) { if (isdigit(token[0])) { output.push_back(token); } else if (token == "(") { operators.push(token); } else if (token == ")") { while (!operators.empty() && operators.top() != "(") { output.push_back(operators.top()); operators.pop(); } operators.pop(); // Pop the '(' } else if (precedence.count(token)) { // Check if it's an operator while (!operators.empty() && precedence[token] <= precedence[operators.top()]) { output.push_back(operators.top()); operators.pop(); } operators.push(token); } } while (!operators.empty()) { output.push_back(operators.top()); operators.pop(); } return output; } int main() { vector<string> tokens = {"(", "3", "+", "4", ")", "*", "5"}; vector<string> postfix = infixToPostfix(tokens); cout << "Postfix expression: "; for (const auto& token : postfix) { cout << token << " "; } cout << endl; return 0; }