(盐城工学院数据结构课程设计)栈的应用表达式求值

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构课程设计报告

栈的应用:表达式求值的设计

专业

学生姓名

班级

学号

指导教师 徐燕萍

完成日期

目录

1设计内容 (1)

2设计分析

2.1系统需求分析 (1)

2.1.1系统目标 (1)

2.1.2主体功能 (1)

2.2系统概要设计 (1)

2.2.1系统的功能模块划分 (1)

2.2.2系统流程图 (2)

3设计实践

3.1基本分析 (3)

3.2中缀表达式求值 (4)

3.3后缀表达式求值 (5)

3.4中缀表达式转换成后缀表达式 (6)

4测试方法

4.1基本测试 (7)

4.2拓展测试 (7)

4.3容错测试 (8)

5程序运行效果 (7)

6设计心得 (8)

7附录:源代码 (10)

栈的应用:表达式求值的设计

1 设计内容

设计一个表达式求值的程序。该程序必须可以接受包含(,),+,-,*,/,%,和^(求幂运算符,a^b=a b)的中缀表达式,并求出结果。如果表达式正确,则输出表达式的结果;如果表达式非法,则输出错误信息。

2 设计分析

2.1系统需求分析

2.1.1系统目标

利用栈设计一个程序,该程序能够用于表达式求值,程序将读入的中缀表达式转换为后缀表达式,然后读取后缀表达式,输出结果。

输入要求:程序从“input.txt”文件中读取信息,在这个文件中如果有多个中缀表达式,则每个表达式独占一行,程序的读取操作在文件的结尾处停止。

输出要求:对于每一个表达式,将其结果放在“output.txt”文件的每一行中。这些结果可能是值(精确到小数点后两位),也可能是错误信息“ERROR IN INFIX NOTATION”。

2.1.2 主体功能

能够处理以字符序列的形式输入的不含变量的实数表达式,正确处理负数与小数,判断表达式是否语法正确(包含分母不能为零的情况),正确实现对算术四则混合运算表达式的求值,能够将计算中遇到的问题和结果以文件的形式予以存储。

2.2系统概要设计

2.2.1系统的功能模块划分

1.判断操作数的函数isnum()

判断当前所指字符是否属于数字,是就返回‘1’,不是就返回‘0’。

2.求运算符优先级函数priority()

为了方便判断运算符优先级,先利用switch函数将不同的运算符返回不同的整型数字,在根据数字的大小判断优先级。‘+’,‘-’优先级相同,返回数字相同,‘*’,‘/’也是。

3.表达式求值函数infix_value()

此函数是直接按照设计思路完成问题要求的函数,其中要调用到判断操作符的函数isnum()和求运算符优先级的函数priority()。循环结束弹出栈2的数值,并返回。

4.主函数main()

定义一个数组存储表达式整个字符串,将返回的数值直接赋值到浮点型的result,输出result。

5.两个栈的函数设计:

栈的初始化函数charInit_SeqStack()

Init_SeqStack()

栈判空 Empty_SeqStack()

char Empty_SeqStack()

入栈函数 Push_SeqStack()

charPush_SeqStack()

出栈函数 Pop_SeqStack()

charPop_SeqStack()

取栈顶函数 GetTop_SeqStack()

charGetTop_SeqStack()

销毁栈 Destory_SeqStack()

charDestory_SeqStack()

2.2.2系统流程图

图1 系统流程图

3设计实践

3.1基本分析

在计算机中,算术表达式的计算往往是通过使用栈来实现的。所以,本表达式求值程序的最主要的数据结构就是栈。可以使用栈来存储输入表达式的操作符和操作数。

输入的表达式是由操作数和运算符以及改变运算次序的圆括号连接而成的式子。

表达式求值是高级语言编译中的一个基本问题,是栈的典型应用实例。任何一个表达式都是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。操作数既可以是常数,也可以是被说明为变量或常量的标识符;运算符可以分为算术运算符、关系运算符和逻辑运算符三类;基本界限符有左右括号和表达式结束符等。

3.2中缀表达式求值

中缀表达式:每个二目运算符在两个运算量的中间,假设操作数是整型常数,运算符只含加、减、乘、除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。要对一个简单的算术表达式求值,首先要了解算术四则运算的规则,即:

(1) 从左到右;

(2) 先乘除,后加减;

(3) 先括号内,后括号外。

运算符和界限符可统称为算符,它们构成的集合命名为OPS。根据上述三条运算规则,在运算过程中,任意两个前后相继出现的算符θ1和θ2之间的优先关系必为下面三种关系之一:

θ1<θ2,θ1的优先权低于θ2。

θ1=θ2,θ1的优先权等于θ2。

θ1>θ2,θ1的优先权高于θ2。

实现算符优先算法时需要使用两个工作栈:一个称作operator,用以存放运算符;另一个称作operand,用以存放操作数或运算的中间结果。算法的基本过程如下:

首先初始化操作数栈operand和运算符栈operator,并将表达式起始符“#”压入运算符栈;

依次读入表达式中的每个字符,若是操作数则直接进入操作数栈operand,若是运算符,则与运算符栈operator的栈顶运算符进行优先权比较,并做如下处理:

(1) 若栈顶运算符的优先级低于刚读入的运算符,则让刚读入的运算符进operator栈;

(2) 若栈顶运算符的优先级高于刚读入的运算符,则将栈顶运算符退栈,送入θ,同时将操作数栈operand退栈两次,得到两个操作数a、b,对a、b进行θ运算后,将运算结果作为中间结果推入operand栈;

(3) 若栈顶运算符的优先级与刚读入的运算符的优先级相同,说明左右括号相遇,只需将栈顶运算符(左括号)退栈即可。operator栈的栈顶元素和当前读入的字符均为“#”时,说明表达式起始符“#”与表达式结束符“#”相遇,整个表达式求解结束。

int ExpEvaluation()

{ /*读入一个简单算术表达式并计算其值。*/

InitStack(&operand); InitStack(&operator);

PushStack(&operator, ’#’);

printf(″\n\n Please input an expression (Ending with #) :″);

相关文档
最新文档