中缀表达式转化为后缀表达式 | 栈

111 阅读1分钟

复习数据结构期末的时候遇到这个栈的应用题,印象不深,重新复习一下。

将中缀表达式转换为后缀表达式(逆波兰表达式)的算法思想如下:

  • 从左向右开始扫描中缀表达式;
  • 遇到数字时,加入后缀表达式;
  • 遇到运算符时: 
    • 若为 ( ,入栈;
    • 若为 ) ,则依次把栈中的运算符加入后缀表达式,直到出现 ( ,从栈中删除 (; 
    • 若为除括号外的其他运算符,当其优先级高于除 ( 外的栈顶运算符时,直接入栈。否则从栈项开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或遇到了一个左括号为止。

当扫描的中级表达式结束时,栈中的所有运算符依次出栈加入后级表达式。

image.png

可以运行的 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/+