利用表达式求值首先要会将中缀表达式变为后缀表达式,过程如下:
中缀表达式:(A+B)*C-D/E = ( ( (A+B)C ) - (D/E) ),将符号移到对应括号的后面。
后缀表达式:AB+CDE/-。
将表达式转化为后缀后能方便利用栈进行计算。
利用栈来化为后缀表达式的步骤如下:
从左往右扫描中缀表达式。当读到数字时,加入后缀表达式。读到操作符时,将其与操作符栈顶进行比较,如果当前符号优先级高或为栈空,就压入栈。否则,一个个往外pop到后缀表达式中,直到当前操作符的优先级比栈顶的高,才将其push。
比较难理解的是,为什么遇到优先级更高的就push,而更低的出现就要pop?
首先要知道计算机算时不会先看后面的,所以我们得把先算的放前面。而在四则运算中是有优先级的,优先级高的即使顺序上在后面也要先进行计算。而栈是FILO,所以可以利用栈来实现先算优先级更高的运算。而如果优先级并不更高就要遵守“在前面的先算”的原则了。所以要pop完优先级更高或一样的。
但如果中缀表达式中有括号呢?
括号的优先级是最高的,要先算。所以对括号的处理:当遇到’(‘时,压入操作符栈;当遇到’)‘时,因为括号里的要先算,所以一直pop直到’('出现。
而有了后缀表达式,计算就十分方便了。如果是数字,就压入栈,如果是操作符,就pop两个数字,计算后放回栈中。最后只会剩下一个数,就是结果。
注意点:
- 因为栈是FILO,所以后一个弹出的数字在运算中是在前面的。
- 除法可能导致小数,数字类型设置为浮点。
- 有两个栈:操作符栈在生成后缀表达式时使用,数字栈在计算时使用。