中缀表达式转后缀表达式

1、前言

Shunting yard算法(调度场算法)是一个用于将中缀表达式转换为后缀表达式的经典算法,由艾慈格.迪杰斯特拉引入,因其操作类似于火车编组场而得名。

例如:3+4

1)将3入输出队列(每当输入一个数字时,直接进入输出队列)

2)将+号压入运算堆栈

3)将4入输出队列

4)输入结束,将操作符堆栈中剩余操作符入输出队列

通过这个例子可以简单的看出两个规则:

  • 当读入一个数字时,直接入输出队列
  • 当输入结束后,运算符队列中所有操作符入输出队列

二、详细的算法

提示:我们将分配一个队列和一个栈,队列主要用于输出后缀表达式,然而栈主要用于保存操作符。

1、读入一个记号

    • 如果该记号为数字,直接将其放到输出队列中;
  • 如果该记号为一个操作符o,则将其与栈顶比较;

        如果栈顶为空,直接将该操作符o压入栈;

        如果该操作符o是左结合性的,

           栈顶的操作符o的优先级大于或等于该操作符的优先级,则弹出栈顶的操作符,然后将操作符o压入栈。否则不弹出,并将操作符o压入栈。

       如果该操作符是右结合性的,

          栈顶的操作符的优先级大于该操作符的优先级,则弹出栈顶的操作符,然后将该操作符压入栈。否则不弹出,并将操作符o压入栈。

       如果该操作符是左括号,那么将其压入栈;

       如果该操作符是右括号,那么从栈当中不断弹出操作符并且放入输出队列中,直到栈顶元素为左括号为止。

2、重复执行

3、当再没有记号可以读取时:则弹出栈中剩下的操作符。

输入: 3 + 4 * 2 / ( 1 − 5 ) ^ 2 ^ 3

输入 动作 输出(逆波兰表达式) 运算符栈 提示
3 将符号加入输出队列 3    
+ 将符号压入操作符堆栈 3 +  
4 将符号加入输出队列 3 4 +  
* 将符号压入操作符堆栈 3 4 *+ *号的优先级高于+号
2 将符号加入输出队列 3 4 2 *+  
/ 将堆栈中元素弹出,加入输出队列;
将符号压入操作符堆栈
3 4 2 *;

3 4 2 *

+;

/ +

/号和*号优先级相同;

/号的优先级高于+号
( 将符号压入操作符堆栈 3 4 2 * ( / +  
1 将符号加入输出队列 3 4 2 * 1 ( / +  
- 将符号压入操作符堆栈 3 4 2 * 1 − ( / +  
5 将符号加入输出队列 3 4 2 * 1 5 − ( / +  
) 将堆栈中元素弹出,加入输出队列;
将堆栈元素弹出
3 4 2 * 1 5 −;

3 4 2 * 1 5 −
( / +

/ +
循环直到找到(号;
括号匹配结束
^ 将符号压入操作符堆栈 3 4 2 * 1 5 − ^ / + ^号的优先级高于/号
2 将符号加入输出队列 3 4 2 * 1 5 − 2 ^ / +  
^ 将符号压入操作符堆栈 3 4 2 * 1 5 − 2

^ ^ / +

^号为从右至左求值
3 将符号加入输出队列 3 4 2 * 1 5 − 2 3 ^ ^ / +  
END 将栈中所有数据加入输出队列 3 4 2 * 1 5 − 2 3 ^ ^ / +    

 

参考于:http://zh.wikipedia.org/wiki/Shunting_yard%E7%AE%97%E6%B3%95

介绍一个人工转换的方法,假设有一个中缀表达式a+b*c-(d+e)

1首先将这个中缀表达式的所有运算加括号((a+(b*c))-(d+e))

2然后将所有运算符放到括号后面,这样就变成了((a(bc)* )+ (de)+ )-

3把所有括号去掉abc*+de+-,最后得出的结果就是后缀表达式

上面这个方法可以在比如做题分析的时候用人脑的时候使用,接下来介绍用程序实现将中缀转换成后缀表达式的思路

参考于:http://www.cnblogs.com/MichaelYin/archive/2012/05/02/2479248.html

posted @ 2013-09-25 21:38  aoguren  阅读(591)  评论(0编辑  收藏  举报