1、表达式求值数据结构课程设计报告项目名称:表达式求值学号:班级:姓名:指导老师: 计算机科学与技术 2014年12月20日1. 问题描述: 表达式求值问题主要是通过使用栈和队列来解决问题。我们在书写表达式时总是以中缀形式输入,也就是将运算符放在操作数中间,但是计算机处理数据时,运算符却跟在两个操作数之后,这种表现形式称为后缀表达式,所以在书写程序时要注意两种表现形式之间的转换。2. 设计思路:一个表达式由运算符和操作数两部分构成,它的操作数由0-9这十个数字构成,它的运算符有+、-、*、/四种。一般在表达式中,括号也会改变表达式运算的优先级,所以将括号也看做运算符,并将其的优先级规定为最低。通过
2、栈将中缀表达式转换成后缀表达式的算法思想:顺序扫描中缀表达式,当读到数字时直接将其送至队列中,当读到运算符时,将栈中所有优先级高于或等于该运算符的运算符出栈,送至输出队列中,再将当前运算符入栈,当读到左括号时,入栈,当读到右括号时,将靠近栈顶的第一个左括号上面的运算符全部依次出栈,送至输出队列中,再删除栈中的左括号。为了方便边界条件(栈空)的判断,提高算法的运行效率,在扫描读入中缀表达式之前、在空栈中预先压入一个“#”字符作为栈底元素,另外,在表达式的最后增加一个“#”字符作为中缀表达式的结束标志,该结束符与栈底元素“#”配对。本算法不包括输入表达式的语法检查,但可以过滤掉输入符号之间的空格。
3、执行上述程序若输入中缀表达式字符串:9-(2*4=7)/5+3#,就会得到后缀表达式:9247*+5/3+.其中,运算符栈和存放后缀表达式的队列的变化过程如表21所示。表21 中缀表达式到后缀表达式的转换过程示例转换步骤中缀表达式的读入运算符栈OS后缀表达式PostQ初始9-(2+4*7)/5+3#空1-(2+4*7/5+3#92(2+4*7)/5+3#-932+4*7)/5+3#-(94+4*7)/5+3#-(9 254*7)/5+3#-(+9 26*7)/5+3#-(+9 2 477)/5+3#-(+*9 2 48)/5+3#-(+*9 2 4 79/5+3#-9 2 4 7 * +105
4、+3#-/9 2 4 7 * +11+3#-/9 2 4 7 * + 5123#+9 2 4 7 * + 5 / -13#+9 2 4 7 * + 5 /- 314空9 2 4 7 * + 5 / - 3 +.后缀表达式的计算在后缀表达式中,不仅不需要括号,而且还完全免除了运算符优先级规则。对于后缀表达式来说,仅仅使用一个自然规则,即从左到右顺序完成计算,这个规则对于计算机而言是很容易实现的。下面将讨论如何用就算计算机了实现计算后缀表达式的算法。如果在表达式中只有一个运算符,如像53*这样的表达式,显然计算过程非常重要,可立即执行。但在多数情况下,后缀表达式中都是多于一个运算符,因此,必须要像
5、保存输入数字一样保存其中间结果。在算法中要有一个数字字符到数值的转换。下面以后缀表达式9247*+5/-3+为例,使用上述算法计算该表达式,计算过程如表2-2所示表2-2 后缀表达式的计算过程示例计算步骤后缀表达式的读入运算结果栈VS初始9 2 4 7 * + 5 / - 3 +空12 4 7 * + 5 / - 3 +924 7 * + 5 / - 3 +2 937 * + 5 /- 3 +4 2 94* + 5 /- 3 +7 4 2 95+ 5 / - 3 +28 2 965 / - 3 +30 2 97/ - 3 +5 30 98- 3 +6 9903 +310+3 311空63.数据
6、结构定义:/操作数栈定义typedef struct float dataMaxSize; int top;OpStack,SeqStack;4.系统功能模块介绍:()流程图如下图所示:5.运行与调试分析:输入表达式:9/(8-5)+66.体会:这次课程设计让我更加了解大一学到的C和数据结构程序设计与算法。设计题目要求不仅要求对课本知识有较深刻的了解,同时要求程序设计者有较强的思维和动手能力和更加了解编程思想和编程技巧。这次课程设计让我有一个深刻的体会,那就是细节决定成败,编程最需要的是严谨,如何的严谨都不过分,往往检查了半天发现错误发生在某个括号,分号,引号,或者数据类型上。就像我在写Pus
7、hStack ()函数时,忘了指针的地址符值不用加*号,这一点小小的错误也耽误了我几十分钟,所以说细节很重要。设计程序时,也要不怕遇到错误,否则会让自己心情烦躁,很难找出错误,要冷静思考。同时也要善于请教别人,因为人总是很难发现自己的错误。在这次程序设计中,我在了解和掌握数据结构程序设计的过程中,发现了自己许多的不足之处,在以后的上机中应更加注意,同时体会到C语言具有的语句简洁,使用灵活,执行效率高等特点,也发现上机的重要作用,特别对算术表达式有了深刻的理解。主程序:#include#includetypedef char DataType;#define MaxSize 50/操作数栈定义t
8、ypedef struct float dataMaxSize; int top;OpStack,SeqStack;/函数声明void InitStack(SeqStack *s);/初始化int StackEmpty(SeqStack s);/判断栈是否为空int GetTop(SeqStack s,DataType *e);/取栈顶元素int PushStack(SeqStack *s,DataType e);/入栈int PopStack(SeqStack *s,DataType *e);/出栈void TranslateE(char s1,char s2);/将中缀表达式转化为后缀表达
9、式float ComputeE(char s);/计算后缀表达式void main() char aMaxSize,bMaxSize; float f; printf(请输入表达式:n); gets(a); printf(中缀表达式为:%sn,a); TranslateE(a,b); printf(转换为后缀表达式为:%sn,b); f=ComputeE(b); printf(该表达式的计算结果为:%fn,f);float ComputeE(char a)/计算后缀表达式的值 OpStack s; /定义一个操作数栈 int i=0; float x1,x2,value,result; s.t
10、op=-1; /初始化栈 while(ai!=0) /依次扫描后缀表达式中的每个字符 if(ai!= &ai=0&ai=0&chtop=0;/把栈顶指针置为0int StackEmpty(SeqStack s)/判断栈是否为空 if(s.top=0)/判断栈顶指针是否为0 return 1; else return 0;int GetTop(SeqStack s,DataType *e)/取栈顶元素 if(s.toptop=MaxSize)/判断栈是否满了 printf(栈已满,不能进栈!n); return 0; else s-datas-top=e;/e元素进栈 s-top+;/修改栈顶指针 return 1; int PopStack(SeqStack *s,DataType *e)/出栈 if(s-top=0) printf(栈已空,不能出栈!n); return 0; else s-top-; *e=(char)s-datas-top; return 1;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1