一、逆波兰式的转换:
简单表达式有三中表示方法:
- 中缀表示法:把双目运算符放在两个运算分量中间。
- 前缀表示法:把双目运算符放在两个运算分量前面, 也称为波兰表示法。
- 后缀表示法:把双目运算符放在两个运算分量后面,也称为逆波兰表示法。
例如:
a+b*c(中缀)-->+a*bc(前缀)-->abc*+(后缀)
逆波兰表示法具有如下优点:
1. 无括号,形式简洁清楚
2. 运算符的顺序与运算的次序完全相同
表达式若能用逆波兰式表达时,就很容易处理,生成相应的目标代码。所以这里先介绍如何将中缀表达式转换成逆波兰表达式。我们运用算符优先法来实现转换。
在转换过程中,要考虑到运算符的优先权,应先设立一个运算符栈,存放暂时不能处理的运算符。
-
|| 的优先级小于&&
-
&&的优先级小于!(!属于单目运算符)
-
( 的优先数小于其右边运算符,但高于其左边的运算符
-
) 的优先数最低,不进运算符栈,也不进输出区
逆波兰表达式生成的算法如下:
从左到右扫描中缀表达式,
当前符号是运算分量,输出分量,继续扫描表达式;
当前符号是运算符,检查符号栈有无运算符,
若符号栈为空,则当前运算符入栈,继续扫描表达式;
若符号栈不为空,则比较当前运算符与栈顶运算符的优先数;
当栈顶运算符大于或等于当前运算符时, 栈顶运算符退栈,送输出流,当前运算符入栈,继续扫描表达式;
当栈顶运算符小于当前运算符时,当前运算符入栈,继续扫描表达式。
注:
-
“(”优先级高于其左边的运算符,低于其右边的运算符。
-
“)”出现时最近出现的“(”右边的所有运算符出栈。
当前符号
|
输入区
|
符号栈
|
输出区
|
(
|
a+b*c)*d
|
|
|
a
|
+b*c)*d
|
(
|
|
+
|
b*c)*d
|
(
|
a
|
b
|
*c)*d
|
(+
|
a
|
*
|
c)*d
|
(+
|
ab
|
c
|
)*d
|
(+*
|
ab
|
)
|
*d
|
(+*
|
abc
|
)
|
*d
|
(+
|
abc*
|
)
|
*d
|
(
|
abc*+
|
*
|
d
|
|
abc*+
|
d
|
|
*
|
abc*+
|
|
|
*
|
abc*+d
|
|
|
|
abc*+d*
|
二、逆波兰式的计算:
我们将中缀表达式转换为逆波兰式后,就可以用相关算法对它进行处理计算了。
逆波兰表达式的处理算法:
首先要设立一个运算分量栈,用来存放暂时不处理的运算分量以及中间运算结果。其具体的步骤如下:
从左到右扫描逆波兰表达式
凡遇到运算分量,则运算分量入栈,继续扫描;
凡遇到运算符,则从运算分量栈的栈顶取出两个或一个分量,与该运算符运算,运算结果放回栈中,继续扫描;
直到整个逆波兰式处理完毕
以上例子中,表达式的运算分量都是单个字母,实际编程实现时,运算分量可能是若干字符组成的串,所以首先我们得将这些串识别成一个整体,存在特定的结构中,方便运算。
了解了基本的算法,我们就可以开始着手设计和实现程序了(未完...)