




已阅读5页,还剩29页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验 表达式求值问题1.问题描述 表达式是数据运算的基本形式。人们的书写习惯是中缀式,如:11+22*(7-4)/3.中缀式的计算按运算符的优先级及括号优先的原则,相同级别从左到右进行计算。表达式还有后缀表达式(如:11 22 7 4 - * 3 / +)和前缀表达式(+ 11 / * 22 - 7 4 3)。后缀表达式和前缀表达式中没有括号,给计算带来方便。如后缀表达式计算时按运算符出现的先后进行计算。本设计的主要任务是进行表达式形式的转换及不同形式的表达式计算。2.数据结构设计 (1)顺序栈类定义:首先应在类中定义成员函数,以此来完成顺序栈的相关操作,如下: class SqStackprivate:T *base; /栈底指针int top; /栈顶int stacksize; /栈容量public:SqStack(int m); /构建函数SqStack()delete base;top=0;stacksize=0; /析构函数void Push(T x); /入栈T Pop(); /出栈T GetTop(); /获取栈顶元素int StackEmpty(); /测栈空void ClearStack(); /清空栈void StackTop(); /返回栈顶指针void StackTranverse(); /显示栈中元素; (2)顺序栈类实现:对顺序栈进行初始化,初始化的首要操作就是创建一个空顺序栈。Step1:申请一组连续的内存空间为顺序栈使用:base=new Tm;if(base=NULL) cout栈创建失败,退出!endl;exit(1);Step2:给栈顶、栈容量赋相应的值:stacksize=m;top=-1;(2)顺序栈入栈:入栈需要在栈顶插入一个新元素并相应的调整栈顶。Step1:首先判断是否栈满,如果栈满,抛出“上溢”信息,无法入栈,否则转入Step2;if(top=stacksize-1) throw 栈满,无法入栈;Step2:栈顶指针增加1;top+;Step3:新元素插入栈顶位置;basetop=x;(3)顺序栈出栈:出栈需要取出栈顶元素,并相应的调整栈顶指针。Step1:首先判断是否栈空,如果栈空,抛出“下溢”信息,无法出栈,否则转入Step2;if(top=-1) throw 栈空,不能出栈;Step2:取出栈顶元素,栈顶指针减1;T x;x=basetop-;Step3:返回栈顶元素;return x;(4)顺序栈取栈顶元素:取栈顶元素是取出栈顶元素的值,但不改变栈。Step1:首先判断是否栈空,如果栈空,抛出“下溢”信息,无法出栈,否则转入Step2;if(top=-1) throw 栈空,栈顶无元素;Step2:取出栈顶元素,返回栈顶元素;return basetop;(5) 判断栈空:判断是否栈空,返回Step1:如果栈空,返回1,否则转Step2;if(top=-1) return 1;Step2:否则返回0;return 0;(6) 清空栈:将栈清空。top=-1(7) 返回栈顶指针:cout栈顶top= =0) coutbasei-t; coutendl;3. 算法设计本实验要求读入中缀表达式,求中缀表达式,将中缀表达式转换成前,后缀表达式,利用前,中,后缀表达式求值,并且能够输出等等操作,这就需要构建相关算法。(1) 首先要将表达式中操作符优先级进行排序,优先级从高到低依次为(,),*,/,+,-,算法如下,利用选择语句比较:char Precede(char t1,char t2) /运算符的优先级比较 char f; switch(t2) case +: case -:if(t1=(|t1=) f=; break; case *: case /:if(t1=*|t1=/|t1=) f=; else f=; break; case (:if(t1=) coutERROR1endl; exit(0); else f=; break; case ):switch(t1) case (:f=; break; case =:coutERROR2; break; case =:switch(t1) case =:f=; break; case (:coutERROR2; return f; (2) 其次,就是判断输入元素是否为运算符,若为运算符,就输出1,否则输出0; int In(char c) / 判断c是否为运算符 switch(c) case+: case-: case*: case/: case(: case): case=:return 1; default:return 0; (3) 构造表达式的运算算法,利用选择语句将运算分类:float Operate(float a,char theta,float b) /实施一次运算 float c; switch(theta) case+:c=a+b; break; case-:c=a-b; break; case*:c=a*b; break; case/:c=a/b; return c; (4) 要求一:中缀表达式求值Step1:首先需要将运算符和运算数分开存放,这就需要分别创建栈:SqStack OP(20);SqStack OD(20);Step2:创建相关字符来存放由键盘输入的字符,并以“=”键结束 char theta; float a,b,d; char c,x; / 存放由键盘接收的字符 char z6; / 存放符点数字符串 int i;OP.Push(=);Step3:当输入为数字元素是,直接存入表达式栈就可以,而当输入是符号元素时,就需要判断优先级并进行存栈出栈操作,如果是非法字符,输出错误,并且不存入;c=*exp+; x=OP.GetTop(); while(c!=|x!=) if(In(c) / 是7种运算符之一 switch(Precede(x,c) case:theta=OP.Pop(); / 退栈并将运算结果入栈 b=OD.Pop(); a=OD.Pop(); OD.Push(Operate(a,theta,b); else if(c=0&c=0&c=9|c=.); zi=0; d=atof(z); / 将字符串数组转为符点型存于d OD.Push(d); else / c是非法字符 coutERROR3endl; exit(0); x=OP.GetTop(); d=OD.GetTop(); return d; (4)中缀表达式转换成后缀表达式:Step1:创建一个操作符栈;char c,x;int i=0;SqStack OP(20);Step2:从左到右扫描读取表达式,执行下列运算,直至表达式结束符。 SqStack OP(20);OP.Push(=); / =是表达式结束标志coutexp:exp=0&c=9)|c=.)postexpi+=c;c=*exp+; 2.2:如果是操作符A2,把操作符栈栈顶的操作符A2与它比较:2.2.1:A1A2,从操作符栈输出所有比A2优先级高的运算符,直至栈顶算符优先级小于A2,A2如操作符栈。if(In(c) / 是7种运算符之一postexpi+= ; x=OP.GetTop();switch(Precede(x,c)case:postexpi+=OP.Pop(); / 运算符出栈输出 break;postexpi=0;(4)中缀表达式转换成前缀表达式:Step1:创建一个操作符栈;char c,x;int i=0;SqStack OP(20);Step2:从右到左扫描读取表达式,执行下列运算,直至表达式结束符;while(*exp != 0) *exp+; OP.Push(=); / =是表达式结束标志c=*exp-;2.1:如果是操作数,输出;if(c=0&c=9)|c=.)preexpi+=c;c=*exp-;2.2:如果是操作符A2,把操作符栈栈顶的操作符A2与它比较:2.2.1:A1A2,从操作符栈输出所有比A2优先级高的运算符,直至栈顶算符优先级小于A2,A2如操作符栈。if(In(c) / 是7种运算符之一preexpi+= ; x=OP.GetTop();switch(Precede(x,c)case:preexpi+=OP.Pop(); / 运算符出栈输出 break;preexpi=0;/while(5)后缀表达式求值:Step1:创建一个栈,作为操作数栈;SqStack OD(20);Step2:执行下列操作,直到表达式结束;2.1:读取表达式:c=*postexp+;2.2:如果是操作数,入操作数栈;if(c=0&c=0&c=9|c=.);zi=0;d=atof(z); / 将字符串数组转为符点型存于dOD.Push(d);2.3如果是操作符A,从操作数栈推出两个操作数a,b,进行运算。并把运算结果入操作数栈;if(In(c)/c为运算符b=OD.Pop ();a=OD.Pop ();OD.Push (Operate(a,c,b);c=*postexp+;c=*postexp+;Step3:栈顶元素即为表达式的值,返回它;v=OD.Pop ();return v;(6)前缀表达式求值;Step1:创建一个栈,作为操作数栈;SqStack OD(20);Step2:执行下列操作,直到表达式结束;2.1:读取表达式:c=*preexp-;2.2:如果是操作数,入操作数栈;if(c=0&c=0&c=9|c=.);zi=0;d=atof(z); / 将字符串数组转为符点型存于dOD.Push(d);2.3如果是操作符A,从操作数栈推出两个操作数a,b,进行运算。并把运算结果入操作数栈;if(In(c)/c为运算符b=OD.Pop ();a=OD.Pop ();OD.Push (Operate(a,c,b);c=*preexp-;c=*preexp-;Step3:栈顶元素即为表达式的值,返回它;v=OD.Pop ();return v;(7)界面设计:界面要求简洁明了,能够方便用户进行功能选择,菜单界面如下:1-创建表达式2-表达式求值3-求后缀表达式4-后缀表达式求值5-求前缀表达式6-前缀表达式求值7-显示表达式8-退出4.运行与测试(1)运行程序,显示菜单,如图所示:(2)创建表达式,由中前后缀表达式计算结果如下图所示: (3)将中缀表达式转化为前后缀表达式: 5.调试记录及收获本次试验为表达式求值实验,首先需要对表达式进行输入存入处理,这就需要利用栈的特性,中缀表达式和中转后都比较容易写出,就是中转前需要将表达式从后往前遍历,这就需要将指针先移到字符串的尾端,我这里运用了while(*exp != 0) *exp+;的代码,将exp移到最后,从右往左对c赋值,然后进行比较。此时得到的前缀表达式就是3 4 7 2 * / 1 + ,此时利用栈的特性,后进先出,将栈顶元素先行压出,这就反转成了前缀表达式 + 1 / * 2 7 4 3 ,此时就大功告成了。本次试验中,实现了表达式的求值和中缀表达式转换成前后缀表达式,更重要的是,我理解了栈的使用方法以及指针的运用方式。附录:程序清单:头文件:/顺序栈类定义template class SqStackprivate:T *base;/栈底指针int top;/栈顶int stacksize;/栈容量public:SqStack(int m);/构建函数SqStack()delete base;top=0;stacksize=0;/析构函数void Push(T x);/入栈T Pop();/出栈T GetTop();/获取栈顶元素int StackEmpty();/测栈空void ClearStack();/清空栈void StackTop();/返回栈顶指针void StackTranverse();/显示栈中元素;/顺序栈类实现template SqStack:SqStack(int m)base=new Tm;if(base=NULL) cout栈创建失败,退出!endl;exit(1);stacksize=m;top=-1;template void SqStack:Push(T x)if(top=stacksize-1) throw 栈满,无法入栈;top+;basetop=x;/couttop:topendl;template T SqStack:Pop()T x;if(top=-1) throw 栈空,不能出栈;x=basetop-;/couttop:topendl;return x;template T SqStack:GetTop()if(top=-1) throw 栈空,栈顶无元素;/couttop:topendl;return basetop;template int SqStack:StackEmpty()if(top=-1) return 1;elsereturn 0;template void SqStack:ClearStack()top=-1;template void SqStack:StackTop()/返回栈顶指针cout栈顶top= top;template void SqStack:StackTranverse()int i=top; while(i=0) coutbasei-t; coutendl; 主函数:#include/cout,cin#includeprocess.h/exit()#includestdio.h/EOF,NULL#include#include / atoi()#includeSqStack.hchar pause;char Precede(char t1,char t2) /算符的优先级比较 char f; switch(t2) case +: case -:if(t1=(|t1=) f=; break; case *: case /:if(t1=*|t1=/|t1=) f=; else f=; break; case (:if(t1=) coutERROR1endl; exit(0); else f=; break; case ):switch(t1) case (:f=; break; case =:coutERROR2; break; case =:switch(t1) case =:f=; break; case (:coutERROR2; return f; int In(char c) / 判断c是否为运算符 switch(c) case+: case-: case*: case/: case(: case): case=:return 1; default:return 0; float Operate(float a,char theta,float b) /实施一次运算 float c; switch(theta) case+:c=a+b; break; case-:c=a-b; break; case*:c=a*b; break; case/:c=a/b; return c; float Val_Exp(char *exp) /中缀表达式求值。设OPTR和OPND分别为运算符栈和运算数栈 SqStack OP(20); SqStack OD(20); char theta; float a,b,d; char c,x; / 存放由键盘接收的字符 char z6; / 存放符点数字符串 int i; OP.Push(=); / =是表达式结束标志 c=*exp+; x=OP.GetTop(); while(c!=|x!=) if(In(c) / 是7种运算符之一 switch(Precede(x,c) case:theta=OP.Pop(); / 退栈并将运算结果入栈 b=OD.Pop(); a=OD.Pop(); OD.Push(Operate(a,theta,b); else if(c=0&c=0&c=9|c=.); zi=0; d=atof(z); / 将字符串数组转为符点型存于d OD.Push(d); else / c是非法字符 coutERROR3endl; exit(0); x=OP.GetTop(); d=OD.GetTop(); return d; void CreatePostExp(char * exp,char * &postexp)/由中缀式求后缀式char c,x;int i=0;SqStack OP(20);OP.Push(=); / =是表达式结束标志coutexp:exp=0&c=9)|c=.)postexpi+=c;c=*exp+;if(In(c) / 是7种运算符之一postexpi+= ; x=OP.GetTop();switch(Precede(x,c)case:postexpi+=OP.Pop(); / 运算符出栈输出 break;postexpi=0;/whilecout后缀表达式为:postexpendl;void CreatePre(char * exp,char * &preexp)/由中缀式求前缀式char c,x;int i=0;SqStack OP(20);coutexp:exp=0&c=9)|c=.)preexpi+=c;c=*exp-;if(In(c) / 是7种运算符之一preexpi+= ; x=OP.GetTop();switch(Precede(x,c)case:preexpi+=OP.Pop(); / 运算符出栈输出 break;preexpi=0;/whilecout前缀表达式为:preexpi-endl;float Val_PostExp(char *postexp)/后缀表达式求值int i;char z6;float v=0,d=0,a,b;char c;SqStack OD(20);c=*postexp+;while(c!=0)if(c=0&c=0&c=9|c=.);zi=0;d=atof(z); / 将字符串数组转为符点型存于dOD.Push(d);if(In(c)/c为运算符b=OD.Pop ();a=OD.Pop ();OD.Push (Operate(a,c,b);c=*postexp+;c=*postexp+;v=OD.Pop ();return v;float Val_PreExp(char *preexp)/前缀表达式求值int i;char z6;float v=0,d=0,a,b;char c;SqStack OD(20);c=*preexp-;while(c!=0)if(c=0&c=0&c=9|c=.);zi=0;d=atof(z); / 将字符串数组转为符点型存于dOD.Push(d);if(In(c)/c为运算符b=OD.Pop ();a=OD.Pop ();OD.Push (Operate(a,c,b);c=*preexp-;c=*preexp-;v=OD.Pop ();return v; /主函数void main()/int i;char exp20=(2.2+5)+4*(5-3.1)=;char *postexp;postexp=new char20;*postexp=0; /char c;float
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年(职业性尘肺病)模拟题库及答案(肇庆)
- 井筒掘砌工突发状况应对考核试卷及答案
- 2025年贵州贵阳公路工程试验检测师资格考试(公共基础)综合能力测试题及答案
- 钟表设计师设备维护与保养考核试卷及答案
- 农发行资阳市乐至县2025秋招笔试热点题型专练及答案
- 玻璃钢制品缠绕工岗前考核试卷及答案
- 玻璃钢制品工知识考核试卷及答案
- 2025年茶艺师(高级)考试题库附答案
- 玻璃制品模具工内部技能考核试卷及答案
- 美容师上岗考核试卷及答案
- 2025届高三化学一轮复习策略讲座
- 50000t天污水厂课程设计
- GB/T 44251-2024腿式机器人性能及试验方法
- 人音版 (五线谱)一年级上册音乐-1 《玩具兵进行曲》教案
- 医药产业园区智慧园区系统建设方案
- 村民集体经济发展规划方案
- 医药行业药品市场营销计划书中的销售预测与预算
- 人教版六年级数学上册第一、二单元试卷及答案
- 20236月信息技术服务管理体系审核员考试试题及答案解析
- 2016年高考语文全国Ⅰ卷《锄》试题及答案
- 小学校园足球课教案(1-2年级3-6年级)
评论
0/150
提交评论