简述:表达式在我们人类的眼里很直观简单,但想让机器理解并进行计算就是问题了,书里介绍了堆栈来变换表达式形式让机器理解的方法— —中缀表达式变换为后缀表达式,再翻译后缀表达式进行计算。但代码实现竟然只有后缀表达式到计算的这一部分,真是fuck,我又搞了好久才实现中缀变换后缀。
在机器内部,任何表达式都是由操作数、运算符和分解符(括号等)组成。本文只讨论简单的算术表达式,即只有数字和加减乘除括号。我们写的算术表达式都称为中缀形式,如:A+(B-C/D)*E,其后缀形式为ABCD/-E*+。
不难发现:(1)后缀形式中的操作数和前缀形式中的操作数排列顺序相同;(2)后缀形式中没有括号,后缀中运算符的排列顺序就是表达式的正确执行次序。
所以,我们可以把机器做算术题分为两步:(1)把中缀形式转换为后缀形式;(2)根据后缀形式计算表达式。
步骤(1):设置一个堆栈来存放运算符,栈顶初始设置为标识符号#(#的加入方便后面的字符比较),先将中缀表达式后加上符号#,再从左到右扫描中缀表达式,当读到操作数就输出,读到运算符(包括#)就根据其与栈顶运算符的优先级判定入栈还是出栈。
我们用x1记录当前栈顶运算符,x2记录当前读到的运算符(读到的数字输出),运算符优先级关系如图:
规则:1、若x1的优先级高于x2的优先级,将x1退栈输出,保持x2不变,并获取新的栈顶运算符继续比较。2、若x1的优先级低于x2,将x2入栈,并继续读中缀里下一个运算符与新的栈顶比较。3、若x1等于x2,且x1为“(”,x2为“)”时,将x1退栈不输出,并继续读中缀里的下一个字符。4、若x1等于x2,且都为“#”,算法结束。
转换过程就不画了,看代码:(写了蛮久逻辑混乱的地方见谅