前缀、中缀、后缀表达式
开宗明义,首先搞清楚概念
- 前缀表达式(波兰表达式):运算符位于操作数之前,如*34
- 中缀表达式(常见数学表达式):如(3+4)*5
- 后缀表达式(逆波兰表达式):如34+5*
如何将中缀表达式转换为逆波兰表达式
算法:
使用两个栈,一个符号栈,一个运算栈
具体计算规则如下:
1.数字直接入队列
2.运算符要与栈顶元素比较
①栈为空直接入栈
②运算符优先级大于栈顶元素优先级则直接入栈
(这里一定注意是优先级大于才可入栈,你可以在网上看到各种抄袭版本,都是大于等于,错都很一致,误人子弟)
③小于或等于则出栈入列,再与栈顶元素进行比较,直到运算符优先级小于栈顶元素优先级后,操作符再入栈
3.操作符是 ( 则无条件入栈
4.操作符为 ),则依次出栈入列,直到匹配到第一个(为止,此操作符直接舍弃,(直接出栈舍弃
最后将符号栈中剩余元素压入计算栈中,要注意的是,此时需要对计算栈的次序逆序输出才为正确的逆波兰式。
代码实现 C++
int priority(char c) //定义优先级
{
switch(c)
{
case '+':
return 1;
case '-':
return 1;
case '*':
return 2;
case '/':
return 2;
default :
return 0;
}
}
stack<string> RPN(string s){
stack<string> sta;
stack<char> ops;
int n = s.size();
for(int i=0;i<n;i++){
//若为连续数字,则连续读取
if(s[i]>='0'&&s[i]<='9'){
int curnum = s[i]-'0';
int j = i+1;
while(s[j]>='0'&&s[j]<='9'){
curnum = curnum*10 + (s[j]-'0');
j++;
}
i=j-1;
sta.push(to_string(curnum));
}
//左括号直接进入符号栈
else if(s[i]=='('){
ops.push(s[i]