论万恶的中缀表达式转前缀
论万恶的中缀表达式转前缀
话说中缀表达式转后缀表达式真是一件乐事。
从CSP-J 2022 T3 来的,因为除了递归拆分,还可以用这种方法来实现对带括号的逻辑表达式进行运算。
参考了这篇博文,https://www.cnblogs.com/hantalk/p/8734511.html
几个转换的规则还是挺清楚的,但其实个人认为把第二点和第四点合成一个比较好,不然是前后冲突的。
分析了一下对面给的js代码,得出主要要实现的有这些:
- 比较优先级。因为这题不论是操作数还是操作符都只有一位,就偷了点懒,略去了拆分数字(秦九韶算法),还有为了方便把数字的优先级设成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;
}
这便是好了。