数据结构课程设计_表达式求值问题

上传人:痛*** 文档编号:90541353 上传时间:2022-05-15 格式:DOC 页数:21 大小:71KB
返回 下载 相关 举报
数据结构课程设计_表达式求值问题_第1页
第1页 / 共21页
数据结构课程设计_表达式求值问题_第2页
第2页 / 共21页
数据结构课程设计_表达式求值问题_第3页
第3页 / 共21页
点击查看更多>>
资源描述
.实验 表达式求值问题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; /构建函数SqStackdelete base;top=0;stacksize=0; /析构函数void Push; /入栈T Pop; /出栈T GetTop; /获取栈顶元素int StackEmpty; /测栈空void ClearStack; /清空栈void StackTop; /返回栈顶指针void StackTranverse; /显示栈中元素; 2顺序栈类实现:对顺序栈进行初始化,初始化的首要操作就是创建一个空顺序栈。Step1:申请一组连续的内存空间为顺序栈使用:base=new Tm;if cout栈创建失败,退出!endl;exit;Step2:给栈顶、栈容量赋相应的值:stacksize=m;top=-1;2顺序栈入栈:入栈需要在栈顶插入一个新元素并相应的调整栈顶。Step1:首先判断是否栈满,如果栈满,抛出上溢信息,无法入栈,否则转入Step2;if throw 栈满,无法入栈;Step2:栈顶指针增加1;top+;Step3:新元素插入栈顶位置;basetop=x;3顺序栈出栈:出栈需要取出栈顶元素,并相应的调整栈顶指针。Step1:首先判断是否栈空,如果栈空,抛出下溢信息,无法出栈,否则转入Step2;if throw 栈空,不能出栈;Step2:取出栈顶元素,栈顶指针减1;T x;x=basetop-;Step3:返回栈顶元素;return x;4顺序栈取栈顶元素:取栈顶元素是取出栈顶元素的值,但不改变栈。Step1:首先判断是否栈空,如果栈空,抛出下溢信息,无法出栈,否则转入Step2;if throw 栈空,栈顶无元素;Step2:取出栈顶元素,返回栈顶元素;return basetop;(5) 判断栈空:判断是否栈空,返回Step1:如果栈空,返回1,否则转Step2;if return 1;Step2:否则返回0;return 0;(6) 清空栈:将栈清空。top=-1(7) 返回栈顶指针:cout栈顶top= top;(8) 输出栈元素:将栈顶指向i,从栈顶输出到栈底。Step1:将栈顶指针赋予i;int i=top;Step2:如果栈不为空,则输出; while=0 coutbasei-t; coutendl;3. 算法设计本实验要求读入中缀表达式,求中缀表达式,将中缀表达式转换成前,后缀表达式,利用前,中,后缀表达式求值,并且能够输出等等操作,这就需要构建相关算法。(1) 首先要将表达式中操作符优先级进行排序,优先级从高到低依次为,*,/,+,-,算法如下,利用选择语句比较:char Precede /运算符的优先级比较 char f; switch case +: case -:ift1= f=; break; case *: case /:if f=; else f=; break; case :if coutERROR1endl; exit; else f=:switch case :f=; break; case =:coutERROR2endl; exit; default: f=; break; case =:switch case =:f=; break; case :coutERROR2endl; exit; default: f=; return f; (2) 其次,就是判断输入元素是否为运算符,若为运算符,就输出1,否则输出0; int In / 判断c是否为运算符 switch case+: case-: case*: case/: case: case=:return 1; default:return 0; (3) 构造表达式的运算算法,利用选择语句将运算分类:float Operate /实施一次运算 float c; switch 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;SqStack OD;Step2:创建相关字符来存放由键盘输入的字符,并以=键结束char theta;float a,b,d; char c,x; / 存放由键盘接收的字符 char z6; / 存放符点数字符串int i;OP.Push;Step3:当输入为数字元素是,直接存入表达式栈就可以,而当输入是符号元素时,就需要判断优先级并进行存栈出栈操作,如果是非法字符,输出错误,并且不存入;c=*exp+; x=OP.GetTop; while ifIn / 是7种运算符之一 switchPrecede case:OP.Push; / 栈顶元素优先权低 c=*exp+; break; case=:x=OP.Pop; / 脱括号并接收下一字符 c=*exp+; break; case:theta=OP.Pop; / 退栈并将运算结果入栈 b=OD.Pop; a=OD.Pop; OD.PushOperate; else if=0&c / c是操作数 i=0; do zi=c; i+; c=*exp+; while=0&c; zi=0; d=atof; / 将字符串数组转为符点型存于d OD.Push; else / c是非法字符 coutERROR3endl; exit; x=OP.GetTop; d=OD.GetTop; return d; 4中缀表达式转换成后缀表达式:Step1:创建一个操作符栈;char c,x;int i=0;SqStack OP;Step2:从左到右扫描读取表达式,执行下列运算,直至表达式结束符。SqStack OP;OP.Push; / =是表达式结束标志coutexp:expendl;c=*exp+; 2.1:如果是操作数,输出;if=0&c|c=.postexpi+=c;c=*exp+; 2.2:如果是操作符A2,把操作符栈栈顶的操作符A2与它比较:2.2.1:A1A2,从操作符栈输出所有比A2优先级高的运算符,直至栈顶算符优先级小于A2,A2如操作符栈。ifIn / 是7种运算符之一postexpi+= ; x=OP.GetTop;switchPrecedecase:OP.Push; / 栈顶元素优先权低 c=*exp+; break; case=:x=OP.Pop; / 脱括号并接收下一字符 c=*exp+; break; case:postexpi+=OP.Pop; / 运算符出栈输出 break;postexpi=0;4中缀表达式转换成前缀表达式:Step1:创建一个操作符栈;char c,x;int i=0;SqStack OP;Step2:从右到左扫描读取表达式,执行下列运算,直至表达式结束符;while *exp+; OP.Push; / =是表达式结束标志c=*exp-;2.1:如果是操作数,输出;if=0&c|c=.preexpi+=c;c=*exp-;2.2:如果是操作符A2,把操作符栈栈顶的操作符A2与它比较:2.2.1:A1A2,从操作符栈输出所有比A2优先级高的运算符,直至栈顶算符优先级小于A2,A2如操作符栈。ifIn / 是7种运算符之一preexpi+= ; x=OP.GetTop;switchPrecedecase:OP.Push; / 栈顶元素优先权低 c=*exp-; break; case=:x=OP.Pop; / 脱括号并接收下一字符 c=*exp-; break; case:preexpi+=OP.Pop; / 运算符出栈输出 break;preexpi=0;/while5后缀表达式求值:Step1:创建一个栈,作为操作数栈;SqStack OD;Step2:执行下列操作,直到表达式结束;2.1:读取表达式:c=*postexp+;2.2:如果是操作数,入操作数栈;if=0&c|c=./为操作数i=0;dozi+=c;c=*postexp+;while=0&c;zi=0;d=atof; / 将字符串数组转为符点型存于dOD.Push;2.3如果是操作符A,从操作数栈推出两个操作数a,b,进行运算。并把运算结果入操作数栈;ifIn/c为运算符b=OD.Pop ;a=OD.Pop ;OD.Push Operate;c=*postexp+;c=*postexp+;Step3:栈顶元素即为表达式的值,返回它;v=OD.Pop ;return v;6前缀表达式求值;Step1:创建一个栈,作为操作数栈;SqStack OD;Step2:执行下列操作,直到表达式结束;2.1:读取表达式:c=*preexp-;2.2:如果是操作数,入操作数栈;if=0&c|c=./为操作数i=0;dozi+=c;c=*preexp-;while=0&c;zi=0;d=atof; / 将字符串数组转为符点型存于dOD.Push;2.3如果是操作符A,从操作数栈推出两个操作数a,b,进行运算。并把运算结果入操作数栈;ifIn/c为运算符b=OD.Pop ;a=OD.Pop ;OD.Push Operate;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+;的代码,将exp移到最后,从右往左对c赋值,然后进行比较。此时得到的前缀表达式就是3 4 7 2 * / 1 + ,此时利用栈的特性,后进先出,将栈顶元素先行压出,这就反转成了前缀表达式 + 1 / * 2 7 4 3 ,此时就大功告成了。本次试验中,实现了表达式的求值和中缀表达式转换成前后缀表达式,更重要的是,我理解了栈的使用方法以及指针的运用方式。附录:程序清单:头文件:/顺序栈类定义template class SqStackprivate:T *base;/栈底指针int top;/栈顶int stacksize;/栈容量public:SqStack;/构建函数SqStackdelete base;top=0;stacksize=0;/析构函数void Push;/入栈T Pop;/出栈T GetTop;/获取栈顶元素int StackEmpty;/测栈空void ClearStack;/清空栈void StackTop;/返回栈顶指针void StackTranverse;/显示栈中元素;/顺序栈类实现template SqStack:SqStackbase=new Tm;if cout栈创建失败,退出!endl;exit;stacksize=m;top=-1;template void SqStack:Pushif throw 栈满,无法入栈;top+;basetop=x;/couttop:topendl;template T SqStack:PopT x;if throw 栈空,不能出栈;x=basetop-;/couttop:topendl;return x;template T SqStack:GetTopif throw 栈空,栈顶无元素;/couttop:topendl;return basetop;template int SqStack:StackEmptyif return 1;elsereturn 0;template void SqStack:ClearStacktop=-1;template void SqStack:StackTop/返回栈顶指针cout栈顶top= top;template void SqStack:StackTranverseint i=top; while=0 coutbasei-t; coutendl; 主函数:#include/cout,cin#includeprocess.h/exit#includestdio.h/EOF,NULL#include#include / atoi#includeSqStack.hchar pause;char Precede /算符的优先级比较 char f; switch case +: case -:ift1= f=; break; case *: case /:if f=; else f=; break; case :if coutERROR1endl; exit; else f=:switch case :f=; break; case =:coutERROR2endl; exit; default: f=; break; case =:switch case =:f=; break; case :coutERROR2endl; exit; default: f=; return f; int In / 判断c是否为运算符 switch case+: case-: case*: case/: case: case=:return 1; default:return 0; float Operate /实施一次运算 float c; switch case+:c=a+b; break; case-:c=a-b; break; case*:c=a*b; break; case/:c=a/b; return c; float Val_Exp /中缀表达式求值。设OPTR和OPND分别为运算符栈和运算数栈 SqStack OP; SqStack OD; char theta; float a,b,d; char c,x; / 存放由键盘接收的字符 char z6; / 存放符点数字符串 int i; OP.Push; / =是表达式结束标志 c=*exp+; x=OP.GetTop; while ifIn / 是7种运算符之一 switchPrecede case:OP.Push; / 栈顶元素优先权低 c=*exp+; break; case=:x=OP.Pop; / 脱括号并接收下一字符 c=*exp+; break; case:theta=OP.Pop; / 退栈并将运算结果入栈 b=OD.Pop; a=OD.Pop; OD.PushOperate; else if=0&c / c是操作数 i=0; do zi=c; i+; c=*exp+; while=0&c; zi=0; d=atof; / 将字符串数组转为符点型存于d OD.Push; else / c是非法字符 coutERROR3endl; exit; x=OP.GetTop; d=OD.GetTop; return d; void CreatePostExp/由中缀式求后缀式char c,x;int i=0;SqStack OP;OP.Push; / =是表达式结束标志coutexp:expendl;c=*exp+;whileif=0&c|c=.postexpi+=c;c=*exp+;ifIn / 是7种运算符之一postexpi+= ; x=OP.GetTop;switchPrecedecase:OP.Push; / 栈顶元素优先权低 c=*exp+; break; case=:x=OP.Pop; / 脱括号并接收下一字符 c=*exp+; break; case:postexpi+=OP.Pop; / 运算符出栈输出 break;postexpi=0;/whilecout后缀表达式为:postexpendl;void CreatePre/由中缀式求前缀式char c,x;int i=0;SqStack OP;coutexp:expendl;while *exp+; OP.Push; / =是表达式结束标志c=*exp-;whileif=0&c|c=.preexpi+=c;c=*exp-;ifIn / 是7种运算符之一preexpi+= ; x=OP.GetTop;switchPrecedecase:OP.Push; / 栈顶元素优先权低 c=*exp-; break; case=:x=OP.Pop; / 脱括号并接收下一字符 c=*exp-; break; case:preexpi+=OP.Pop; / 运算符出栈输出 break;preexpi=0;/whilecout前缀表达式为:preexpi-endl;float Val_PostExp/后缀表达式求值int i;char z6;float v=0,d=0,a,b;char c;SqStack OD;c=*postexp+;whileif=0&c|c=./为操作数i=0;dozi+=c;c=*postexp+;while=0&c;zi=0;d=atof; / 将字符串数组转为符点型存于dOD.Push;ifIn/c为运算符b=OD.Pop ;a=OD.Pop ;OD.Push Operate;c=*postexp+;c=*postexp+;v=OD.Pop ;return v;float Val_PreExp/前缀表达式求值int i;char z6;float v=0,d=0,a,b;char c;SqStack OD;c=*preexp-;whileif=0&c|c=./为操作数i=0;dozi+=c;c=*preexp-;while=0&c;zi=0;d=atof; / 将字符串数组转为符点型存于dOD.Push;ifIn/c为运算符b=OD.Pop ;a=OD.Pop ;OD.Push Operate;c=*preexp-;c=*preexp-;v=OD.Pop ;return v; /主函数void main/int i;char exp20=+4*=;char *postexp;postexp=new char20;*postexp=0; /char c;float v1;system;/执行系统命令cls,清屏int choice; do/显示主菜单cout1-创建表达式n;cout2-表达式求值n;cout3-求后缀表达式n;cout4-后缀表达式求值n;cout5-求前缀表达式n;cout6-前缀表达式求值n;cout7-显示表达式n;cout8-退出n;coutchoice;switchcase 1:/创建表达式cout请输入表达式,以=结束exp;cin.get;system;break;case 2:/表达式求值v1=Val_Exp ;coutexp;coutv1endl;cin.get; system;break;case 3:/求后缀表达式CreatePostExp;cin.get;system;break;case 4:/后缀表达式求值v1=Val_PostExp;coutpostexp=v1endl;cin.get;system;break;case 5:/求前缀表达式CreatePre;cin.get;system;break;case 6:/前缀表达式求值v1=Val_PreExp;coutpostexp=v1endl;cin.get;system;break;case 7:/ 显示表达式coutendl;cout已创建的表达式为:;coutexpendl;ifstrlencout后缀表达式为:;coutpostexpendl; cin.get; system;break;case 8:/退出cout结束运行,Bye-Bye!endl;break;default:/coutInvalid choicen;break;while;/end main.
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!