数据结构——中缀表达式
数据结构——中缀表达式
利用中缀表达式直接求值
要实现中缀表达式直接求值,必须设置两个栈,一个栈用于存放操作数,记作
OPND; 另一个栈用于存放操作符,记作 OPTR。
中缀表达式求值算法步骤如下:
- 初始化:操作符栈中放置一个元素
@。 - 依次读取中缀表达式中的每一个字符,对于不同类型的字符按以下情况处理:
- 若读到的是操作数,则压入操作数栈,并读取下一个字符。
- 若读到的是操作符
c,则将操作符栈的栈顶元素pre_op与之进行比较,会出现以下 3 种情况:- 若
pre_op < c,则将c入栈,并读取下一个字符。 - 若
pre_op = c,则将pre_op出栈,并读取下一个字符。 - 若
pre_op > c,则将pre_op出栈,并在操作数栈中退栈 2 次,依次得到操作数b和a,然后进行a pre_op b运算,将运算结果压入操作数栈。
- 若
- 扫描完毕时,操作数栈中只有一个元素,即计算结果。
1 | //中缀表达式,实数 |
Precede(pre_op, ch)为进行算符优先级比较的函数
Operate(a, pre_op, b)为计算函数
利用后缀表达式求值
优点
后缀是指把操作符放在两个操作数的后面。采用后缀表示的算术表达式被称为后缀表达式或后缀算。 在后缀表达式中,完全按照操作符出现的先后顺序进行计算过程,不存在括号,也不存在优先级的差别。
将中缀表达式转换成等价的后缀表达式求值时,不需要再考虑操作符的优先级,只需从左到右扫描一边后缀表达式即可。只需设置一个OPND栈用于存放操作数
先将中缀表达式转成后缀表达式
把中缀表达式转换为后缀表达式算法的基本思路如下:
初始化:操作符栈中放置一个元素
@。依次读入中缀表达式中的每个字符
,对于不同类型的字符按不同情况进行处理:
- 若读到的是操作数,则输出该操作数,并读取下一个字符。
- 若读到的是左括号
(,则把它压入OPTR栈中,并读取下一个字符。 - 若读到的是右括号
),则表明括号内的中缀表达式已经扫描完毕,将OPTR栈从栈顶直到左括号之前的操作符依次出栈并输出,然后将左括号出栈,并读取下一个字符。 - 若读到的是操作符
c,则将操作符栈的栈顶元素pre_op与之进行比较:- 若
pre_op < c,则将c入栈,并读取下一个字符。 - 若
pre_op >= c,则将pre_op出栈并输出。
- 若
- 若读到的是结束符
@,则把栈中剩余的操作符依次出栈并输出,即可得到转换成的后缀表达式。
后缀表达式求值
后缀表达式求值算法的基本思路如下
依次读入后缀表达式中的每个字符
,直至表达式结束。
- 若读到的是操作数,则入
OPND栈。 - 若读到的是操作符,则在
OPND栈中退栈两个元素(先退出的是操作符右侧,后退出的是操作符左侧),然后用该操作符进行运算,并将运算结果压入OPND栈中。
- 若读到的是操作数,则入
后缀表达式扫描完毕时,若
OPND栈中仅有一个元素,即为运算结果。