1、定义
前缀表达式(波兰表达式)就是不含括号的算术表达式,而且它是将运算符写在前面,操作数写在后面的表达式,也称为波兰表达式。例如,- 1 + 2 3,它等价于1-(2+3)。后缀表达式(逆波兰表达式)运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序
中缀表达式就是我们日常使用的,如:(2 + 1) * 3 。
注:运算符优先级
低 -> 高
+ - * / %
实际上如:+和-也有优先级,不过对运算结果(表达式可能不同)无影响,在此忽略了
2、中缀表达式转化为前缀表达式
2.1 算法描述
(1)首先构造一个运算符栈S1和一个储存中间结果的栈S2。
(2)从右至左扫描中缀表达式
(3)如果是操作数时,将其压入S2。
(4)如果是运算符,则与S1栈顶元素比较优先级:
- 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;
- 否则,若该运算符优先级比栈顶运算符的较高或相等,也将运算符压入S1;
- 否则,将S1栈顶的运算符弹出并压入到S2中,再与S1中新的栈顶运算符相比较
(5)遇到括号时:
- 如果是右括号“)”,则直接压入S1;
- 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号 丢弃;
(6)重复步骤(2)至(5),直到表达式的最左边;
(7)若表达式扫描完,将S1中剩余的运算符依次出栈并压入S2;
(8)依次将S2中的元素出栈,结果即为对应的前缀表达式。
2.2 将中缀表达式3+5*(2+6)-1转化为前缀表达式过程:
最后依次将S2中的元素出栈得:-+3*5+261
2.3 用前缀表达式的求值
对于一个前缀表达式的求值而言,需要使用一个栈S
(1)从右至左扫描表达式
(2)如果是操作数,则将其入栈S1
(3)如果是运算符,则将栈S出栈2次,将出栈的两个数作相应的运算(注意前后顺序,先出栈的在左边),然后把得到的结果入栈S。
(4)一直扫描到表达式的最左端时,最后运算的值也就是表达式的值。
前缀表达式:-+3*5+261
3、中缀表达式转化为后缀表达式
3.1 算法描述
(1)首先构造一个运算符栈S1和一个储存中间结果的栈S2。
(2)从左至右扫描中缀表达式
(3)如果是操作数时,将其压入S2。
(4)如果是运算符,则与S1栈顶元素比较优先级:
- 如果S1为空,或栈顶运算符为右括号“(”,则直接将此运算符入栈;
- 否则,若该运算符优先级比栈顶运算符的较高或相等,也将运算符压入S1;
- 否则,将S1栈顶的运算符弹出并压入到S2中,再与S1中新的栈顶运算符相比较
(5)遇到括号时:
- 如果是左括号“(”,则直接压入S1;
- 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;
(6)重复步骤(2)至(5),直到表达式的最右边;
(7)若表达式扫描完,将S1中剩余的运算符依次出栈并压入S2;
(8)从左往右依次读取S2中的元素,即为对应的后缀表达式。
和转化前缀表达式的区别是最开始扫描和最后读取方向不同
具体计算略
2.3 用前缀表达式的求值
同上。
另外其实还有一个更好的方法,适合笔算,不适合机器。
如:3+5*(2+6*4-8)-
根据实际先后计算顺序算
x=6*4=64*
x=2+x=264*+
x=x-8=264*+8-
x=3+x=3264*+8-+
x=x-1=3264*+8-+1-
其实这才是真正正确的,上面都是忽略了+和-,*和/ 的优先顺序的。