复习数据结构期末的时候遇到这个栈的应用题,印象不深,重新复习一下。
将中缀表达式转换为后缀表达式(逆波兰表达式)的算法思想如下:
- 从左向右开始扫描中缀表达式;
- 遇到数字时,加入后缀表达式;
- 遇到运算符时:
- 若为
(,入栈; - 若为
),则依次把栈中的运算符加入后缀表达式,直到出现(,从栈中删除(; - 若为除括号外的其他运算符,当其优先级高于除
(外的栈顶运算符时,直接入栈。否则从栈项开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或遇到了一个左括号为止。
- 若为
当扫描的中级表达式结束时,栈中的所有运算符依次出栈加入后级表达式。
可以运行的 C++ 代码:
#include <iostream>
#include <stack>
std::string infixToPostfix(std:: string infix)
{
std::stack<char> opstk; // stack to store operators
std::string postfix = ""; // postfix notation string
for (char c : infix) {
if (c >= 'a' && c <= 'z') { // append the operand to postfix directly
postfix += c;
} else {
if (c == '(') { // encounter '(' push into the stack
opstk.push(c);
} else if (c == ')') { // encounter ')' pop all operators untill '('
while (opstk.top() != '(') {
postfix += opstk.top();
opstk.pop();
}
opstk.pop(); // pop '('
} else if (c == '+' || c == '-') { // encounter '+' or '-'
while (!opstk.empty() && opstk.top() != '(') {
// append prior or equal operators to postfix untill the stack is empty or encounter '('
postfix += opstk.top();
opstk.pop();
}
opstk.push(c); // push c into the stack
} else if (c == '*' || c == '/') { // encounter '*' or '/'
while (!opstk.empty() && (opstk.top() == '*' || opstk.top() == '/') && opstk.top() != '(') {
// append prior or equal operators to postfix untill the stack is empty or encounter '('
postfix += opstk.top();
opstk.pop();
}
opstk.push(c); // push c into the stack
}
}
}
while (!opstk.empty()) { // append surplus operators in the stack to postfix
postfix += opstk.top();
opstk.pop();
}
return postfix;
}
int main(int argc, char **argv)
{
std::string infix;
std::cin >> infix;
std::cout << infixToPostfix(infix);
return 0;
}
运行结果:
a/b+(c*d-e*f)/g
ab/cd*ef*-g/+