数据结构与算法分析c++:栈的应用(3)

中缀表达式转后缀表达式

中缀表达式转换成后缀表达式的方法阐述

依旧利用栈这种数据结构,本文只是以+、-、*、/、()几个运算符为例,有兴趣的小伙伴可以自己拓展。
如何将a + b * c + ( d * e + f ) * g形式的中缀表达式转换成后缀表达式呢?
先上正确答案,abc*+de*f+g*+

步骤如下:

· 建立一个空栈;
· 遍历字符串。当读到操作数时,直接输出;
· 当读到运算符时:
a 若为 ‘(‘,入栈;
b 若为 ‘)’,则依次把栈中的的运算符加入后缀表达式中,直到出现’(‘,从栈中删除’(’ ;
c 若为除括号外的其他运算符, 当其优先级高于除’(‘以外的栈顶运算符时,直接入栈。
d 否则,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或者遇到了一个左括号为止。
e 遍历结束时,栈中的所有运算符出栈;

那废话不多说,直接上代码。第一个函数int sortOperator(char c)主要是给运算符规定优先顺序,方便后续判断,可以看出如果想添加运算符种类的话,在这个函数扩展也很方便;第二个函数void infixToPostfix(string expression)就是实现转换的函数了。

#include <iostream> 
#include <stack>
#include <string> 
using namespace std;

int sortOperator(char c) {
    switch (c)
    {
    case ')':
        return 0;
    case '*':
        return 1;
    case '/':
        return 1;
    case '+':
        return 2;
    case '-':
        return 2;
    case '(':
        return 3;
    default:
        return -1;
    }
}

void infixToPostfix(string expression){
    stack<char> s;
    for (int i = 0; i < expression.length();i++) {
        //字母代表操作数,直接输出
        if (expression.at(i) >= 'a' && expression.at(i) <= 'z') {
            cout << expression.at(i) << "";
        }
        //去除空格
        else if (expression.at(i) == ' ') {}
        else
            switch (expression.at(i)){
            //左括号直接入栈
            case '(':
                s.push(expression.at(i));
                break;
            //同级运算符写一种就可以,因为sortOperator返回值相同,这里未做省略
            //这里还要注意sortOperator的返回值和实际运算优先级相反,
            //也可调整为和实际运算优先级相同,方便理解。
            case'*':
                //栈非空,且栈顶运算符优先级高于或等于当前运算符,出栈并输出,直到栈顶运算符
                //优先级低于当前运算符,该运算符入栈
                while (!s.empty() && 
                    sortOperator(s.top()) <= sortOperator('*')) {
                    cout << s.top();
                    s.pop();
                }
                s.push(expression.at(i));
                break;

            case '/':
                while (!s.empty() &&
                    sortOperator(s.top()) <= sortOperator('/')) {
                    cout << s.top();
                    s.pop();
                }
                s.push(expression.at(i));
                break;

            case '+':
                while (!s.empty() &&
                    sortOperator(s.top()) <= sortOperator('+')) {
                    cout << s.top();
                    s.pop();
                }
                s.push(expression.at(i));
                break;

            case '-':
                while (!s.empty() &&
                    sortOperator(s.top()) <= sortOperator('-')) {
                    cout << s.top();
                    s.pop();
                }
                s.push(expression.at(i));
                break;

            case ')':
                //遇到右括号,一直进行出栈操作并输出,直到遇到左括号结束循环,再将左括号
                //出栈,且不输出
                while (!s.empty() && s.top() != '(')
                {
                    cout << s.top() << "";
                    s.pop();
                }
                s.pop();
                break;

            default:
                break;
        }

    }
    //遍历表达式后,栈内所有操作符依次出栈并输出。
    while (!s.empty())
    {
        cout << s.top() << "";
        s.pop();
    }
    cout << endl;
}

测试代码如下,

int main(int argc, char* argv[])
{
    cout << "input expression" << endl;
    string line; 
    getline(cin, line);
    infixToPostfix(line);
    system("pause");
    return 0;
}

结果

有兴趣的小伙伴,可以尝试多添加几种运算符,^, ! 等等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章