在严蔚敏的《数据结构》第三章中介绍了栈和队列,这两种结构是线性表的特殊情况,都可以用单向链表来实现。在栈的应用举例中,书中提到可以用栈来实现对数学表达式的求值。于是就实现一个仅包含数字和有限数学符号(+、-、*、/、(、))的数学表达式求值程序。
2、数学符号优先级关系表
3、计算过程概述
程序的实现思路如下:
1、用户输入数学表达式;
2、从左至右扫描表达式,识别数字和数学符号,将识别出的内容保存到队列中
3、对队列中的内容进行分析,计算表达式的值。
其中比较重要的几点如下:
1、内容识别
程序用下面的结构保存识别出的内容,依次检测用户输入的字符串,判断每个字符是数字还是数学符号。
typedef struct _Element
{
char Type; // 元素类型,分为两类,1为操作符,2为操作数
union
{
char Opt; // 如果是操作符,保存其值,可以取+、-、*、/、(、)
float Number; // 操作数
}Value;
struct _Element* pNext;
}Element,*pElement;
这张表在程序中至关重要,程序根据这张表提供的优先级关系来确定哪些先计算,哪些后计算。表的纵坐标表示的是关系式中靠左的数学符号,横坐标表示的是在其后的第二个数学符号,#号表示的是起始和结束指示符。

计算过程与两个栈,一个栈保存数学运算符,另一个保存数字。表达式从左到右解析时,如果栈中的运算符(简称OptInStack)优先级比目前扫描到的关系符(简称OptOnLine)优先级低,则说明OptOnLine应该先算,但是OptInline是二元操作符,它的前面的数已经被解析出来并且被压到保存数字的栈中,但是它的第二个操作数还没有被扫描到,这时候想计算但是内容不全,只有先将运算符压入数学运算符栈中,等它需要的操作数被扫描解析出来之后再算。如果OptInStack的优先级比OptOnLine高,则说明OptInStack所需要的数据都已经准备全,放到保存数字的栈中,这时候可以进行计算了。
下面是程序截图:

具体的内容可以参考严蔚敏的书。
相关程序的链接地址放在下面的链接中,名字是MathCalculate.rar: