论万恶的中缀表达式转前缀

论万恶的中缀表达式转前缀

话说中缀表达式转后缀表达式真是一件乐事。
从CSP-J 2022 T3 来的,因为除了递归拆分,还可以用这种方法来实现对带括号的逻辑表达式进行运算。
参考了这篇博文,https://www.cnblogs.com/hantalk/p/8734511.html
几个转换的规则还是挺清楚的,但其实个人认为把第二点和第四点合成一个比较好,不然是前后冲突的。
分析了一下对面给的js代码,得出主要要实现的有这些:

  1. 比较优先级。因为这题不论是操作数还是操作符都只有一位,就偷了点懒,略去了拆分数字(秦九韶算法),还有为了方便把数字的优先级设成0.

于是便上手写,第一遍裸写,没调,出来的东西是这样的:

#include <bits/stdc++.h>
using namespace std;

queue<char> Q, P;
stack<char> S;

void clear(queue<char> &q)
{
    queue<char> empty;
    swap(empty, q);
}

void clear(stack<char> &s)
{
    stack<char> empty;
    swap(empty, s);
}

int getP(char a)
{
    switch (a)
    {
    case '0':
    case '1':
        return 0;
    case '|':
        return 1;
    case '&':
        return 2;
    case '!':
        return 3;
    case '(':
    case ')':
        return 4;
    }
}

void change(string str)
{
    clear(Q);
    clear(P);
    clear(S);
    for (int i = 0; i < str.length(); i++)
        Q.push(str[i]);
    while (!Q.empty())
    {
        if (getP(Q.front()) == 0)
        {
            P.push(Q.front());
            Q.pop();
        }
        else if (Q.front() != ')')
        {
            if (S.empty())
                S.push(Q.front());
            else
            {
                while (!S.empty() && getP(S.top()) >= getP(Q.front()) && S.top() != '(')
                {
                    P.push(S.top());
                    S.pop();
                }
                S.push(Q.front());
            }
            Q.pop();
        }
        else
        {
            //cout << S.size() << endl;
            while(S.top() != '(')
            {
                P.push(S.top());
                S.pop();
            }
            S.pop();
            Q.pop();
        }
    }
    while(!P.empty())
    {
        cout << P.front() << " ";
        P.pop();
    }
}

int main()
{
    string s = "0&(1|0)|(1|1|1&0)";
    //getline(cin , s);
    change(s);
    return 0;
}

不出所料,炸了。一查,没有把右括号弹出去,没有加判断条件.
改一下:

#include <bits/stdc++.h>
using namespace std;

queue<char> Q, P;
stack<char> S;

void clear(queue<char> &q)
{
    queue<char> empty;
    swap(empty, q);
}

void clear(stack<char> &s)
{
    stack<char> empty;
    swap(empty, s);
}

int getP(char a)
{
    switch (a)
    {
    case '0':
    case '1':
        return 0;
    case '|':
        return 1;
    case '&':
        return 2;
    case '!':
        return 3;
    case '(':
    case ')':
        return 4;
    }
}

void change(string str)
{
    clear(Q);
    clear(P);
    clear(S);
    for (int i = 0; i < str.length(); i++)
        Q.push(str[i]);
    while (!Q.empty())
    {
        if (getP(Q.front()) == 0)
        {
            P.push(Q.front());
            Q.pop();
        }
        else if (Q.front() != ')')
        {
            if (S.empty())
                S.push(Q.front());
            else
            {
                while (!S.empty() && getP(S.top()) >= getP(Q.front()) && S.top() != '(')
                {
                    P.push(S.top());
                    S.pop();
                }
                S.push(Q.front());
            }
            Q.pop();
        }
        else
        {
            //cout << S.size() << endl;
            while(S.top() != '(')
            {
                P.push(S.top());
                S.pop();
            }
            S.pop();
            Q.pop();
        }
    }
    while(!P.empty())
    {
        cout << P.front() << " ";
        P.pop();
    }
    
}

int main()
{
    string s = "0&(1|0)|(1|1|1&0)";
    //getline(cin , s);
    change(s);
    return 0;
}

这便是好了。

posted @ 2022-11-28 22:42  liziyu0714  阅读(30)  评论(0编辑  收藏  举报