用栈进行表达式求值

先简单地阐述一下运算符的3个规则:
①先乘方、开方,再乘、除,最后才是加、减;
②从左到右运算
③有括号得先算括号里的,再算括号外的。

对于字符一个一个地 getchar(),如果这个字符是数字的话,那么就将其压入数据栈,如果是运算符那么就压入算符栈,但运算算符压入算符栈前需要经过一定的处理。
不同运算符有不同的运算优先权,所以要按照一定的优先权计算,但又不仅仅是运算符优先权那么简单~
从数学角度,如果扫描到的运算符优先级  <  栈顶的算符优先级,那么毫无疑问得先算栈顶的算符;如果扫描到的运算符优先级  =   栈顶的算符优先级呢?因为规则②,要从左到右运算,那么还是得先算栈顶的算符,所以说, 如果数学角度的 getchar() <= stact.peak(),那么编程角度的就是  getchar() < stact.peak()  。

如果扫描到“(”呢?因为得先算括号里的,所以它比栈顶的任何算符,+-*/^都要高,所以将"("压栈;
扫描到"("之后,继续扫描算符,这时不管扫描到什么运算符,因为要先算括号里的再算括号外的,所以+-*/^不管什么算符都比“(”要高,所以要将扫描到的算符压栈。
这时,会有同学有疑问,为啥“(”的优先级一会比谁都高,一会比又比谁都低呢?这个是为了同一个目的——先算括号里的。那什么时候比谁都高,什么时候比谁都低呢?当“(”作为扫描到的算符时,它比谁都高;当作为栈顶的算符时,它比谁都低。

如果扫描到“)”呢?这个时候,可以证明括号里只剩下最后一步运算,这时把数据栈里的两个数据,和算法栈里的一个算符,弹出,进行运算,然后压入数据栈里。换句话说,“)”低于除“(”外的任何算符。之后算符栈栈顶的符号是“(”,“)”的优先级和“(”是相等,这时这两符号都没啥用,可以扔了,“)”不比压栈,而栈顶的“(”得弹出扔掉,这就是所谓的  脱括号  。

总结就是(下面的优先级均是指编程优先级):
1)  若优先级getchar() > stack.peak(),getchar()入栈
2)若优先级getchar() = stack.peak(),脱括号并接受下一个字符(只有 右括号 和 左括号 相等这一情况)
3)若优先级getchar() < stack.peak(),当前栈顶运算符stack.peak()出栈,即执行stack.pop(),操作数栈顶的两个操作数退栈与操作符一起运算,并将运算结果入操作数栈;(这种情况是数学角度的  优先级   getchar() <= stack.peak() )
(要区分这些优先级的特别之处哦~)

猜你喜欢

转载自blog.csdn.net/yesyes120/article/details/80252555