后缀表达式也称逆波兰表达式,为什么要叫逆波兰表达式嘞?当然是因为有一个波兰人发明了波兰表达式,而逆的波兰表达式就被叫做“逆波兰表达式”喽!
我们一般表述一个算式的时候通常为:X+Y,即为:“操作数1 操作符 操作数2”,而比较特殊一点的就是平方根函数:“sqrt(N)”,sqrt为操作符,N是操作数。
而逆波兰表达式则是先操作数,后表达式。
eg:12*(3+4)-6+8/2 转换为 1234+*6-82/+
将中缀表达式转换为后缀表达式的算法如下:
1、操作符栈初始化,将结束符#进栈,然后读取中缀表达式中的首字符ch
2、重复执行以下步骤,直到ch=’#’,同时栈顶的操作符也是‘#’时,循环终止
a 若ch是操作数则直接输出,读取下一个字符
b 若ch是操作符,判断ch的优先级icp和当前位于栈顶的操作符op的优先级isp:
若icp(ch) > isp(op),令ch进栈,读入下一个字符ch;
若icp(ch) < isp(op),退栈并输出
若icp(ch) == isp(op),退栈但不输出,若退出的是‘(’,继续读入下一个字符ch
3、算法结束,输出的序列即为后缀表达式
#include<iostream>
using namespace std;
#include<stack>
enum OPERATOR
{
ADD, SUB, MUL, DIV, DATA
};
struct Cell
{
OPERATOR _op;
int _data;
};
//计算后缀表达式
int CalcRPN(Cell* RPN, int size)
{
stack<int> s;
for(int i=0; i<size; ++i)
{
if(DATA == RPN[i]._op) //取到数字
{
s.push(RPN[i]._op);
}
else //取到符号
{
int right = s.top();
s.pop();
int left = s.top();
s.pop();
switch(RPN[i]._op)
{
case ADD:
s.push(left + right);
break;
case SUB:
s.push(left - right);
break;
case MUL:
s.push(left * right);
break;
case DIV:
//检测除数是否为0
if(right)
{
s.push(left / right);
}
break;
}
}
}
return s.top();
}