




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、数据结构课程设计题 目 求解算术表达式 姓 名 吴楚杰 汤友松 杨基长 徐涛 杨剑学 号 33 30 36 35 37 系 别 计算机系 专 业 网络工程 级 别 2008 班 级 二班 2009年 12 月 30日 一、问题描述:设计一个程序,求解算术表达式。【基本要求】以字符序列的形式从键盘输入语法正确的、不含变量的整数表达式,实现对算术四则混合运算表达式的求值。二、问题分析:1) 数据结构描述1、为了实现算符优先算法使用两个工作栈,一个称作optr,用以寄存运算符;另一个称作opnd,用以寄存操作数或运算结果。2、在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作
2、数入opnd,操作符入optr。3、开始将#入操作符栈,通过一个函数来判别算术运算符的优先级。且规定#的优先级最低。在输入表达式的最后输入#,代表表达式输入结束。在表达式输入过程中,遇操作数则直接入栈。遇到运算符则与栈顶运算符比较优先级,当前运算符优先级高(前面的运算还不应执行)则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符(注意当前运算符未变)与新栈顶运算符。如此重复直到栈顶运算符与当前符号均为#,运算结束。 4、通过字符型数组的比较 确定进入工作界面的密码。原始密码已经定了,但是注册的密码 由一个数组来保存。再次登录的时候就可
3、以通过比较原始密码和注册码来决定是否进入。而且登陆次数限定在三次,错误次数也限定在三次。这样就人性化的允许犯错,但是又可以防止不法分子的偷盗行为。2)主要算法流程描述:1、栈的节构体形式typedef struct sqstack/计算数的结构体 elemtype *top;/栈顶指针 elemtype *base;/栈底指针 elemtype stacksize;/栈的大小sqstack,*linklist;/机构体名和结构体指针typedef struct sqstack1/计算符的结构体 char *top; char *base; elemtype stacksize;sqstack1
4、,*linklist1;2、栈的初始化elemtype initstack(linklist s)/初始化栈 s-base=(elemtype*)malloc(stack_size*sizeof(elemtype); if(!s-base) return error ; s-top=s-base; s-stacksize=stack_size; return ok;elemtype initstack1(linklist1 s)/初始化栈 s-base=(char*)malloc(stack_size*sizeof(char); if(!s-base) return error ; s-top
5、=s-base; s-stacksize=stack_size; return ok;3、入栈elemtype push(linklist s,elemtype e)/进栈 if(s-top-s-base=s-stacksize) s-base=(elemtype*)realloc(s-base,(s-stacksize+stack_increasement)*sizeof(elemtype); if(!(s-base) return 0; s-top=s-base+s-stacksize; s-stacksize+=stack_increasement; *(+s-top)=e; retur
6、n 1;elemtype push1(linklist1 s,char e)/进栈if(s-top-s-base=s-stacksize) s-base=(char*)realloc(s-base,(s-stacksize+stack_increasement)*sizeof(char); if(!(s-base) return 0; s-top=s-base+s-stacksize; s-stacksize+=stack_increasement; *(+s-top)=e; return 1;4、取栈顶元素elemtype gettop(sqstack s)/取栈顶元素 elemtype e
7、; if(s.top=s.base) printf(no number left !); return error; e=*s.top; return e; char gettop1(sqstack1 s)/取字符栈顶元素 char e; if(s.top=s.base)/判断有无字符 printf(no number left !); return error; e=*s.top; return e; 5、栈的优先级判断及其函数+ - * / ( ) # + - * / ( ) # =运算符的优先级判断函数:char precede(char top,char c)/top为操作符的栈顶元素
8、,c为当前输入操作符,若c的优先级大于top返回,c与top构成括号匹配返回= char result; switch(c) case #:result=;break; case +: case -:if(top=#|top=() result=;break; case *: case /:if(top=*|top=/)result=; else result=;break; case (: result=;break; default: printf(the operater is out of band.n); / switchreturn result;6、具体运算函数elemtype
9、operate(elemtype a,char theta,elemtype b)/计算式的计算 elemtype result; switch(theta) case +: result=a+b;break; case -: result=a-b;break; case *: result=a*b;break; case /:if(b=0)/特殊计算特殊处理 printf(分母为0,the result is errorn); result=0; else result=a/b;break;default: printf(nthe operater is wrong.n); return r
10、esult;7、运算主函数elemtype evaluate(linklist opnd,linklist1 optr) elemtype flag=0;/当flag为0时表示上一个输入的是字符符号,当其为1时表示上一个输入的是数字字符 elemtype a,l,f; char theta,c,e; c=getchar(); while(c!=#|gettop1(*optr)!=#)/当不是终止符或者是开始符时继续 if(!in(c)/c若为操作数则入opnd栈 if(flag=1)/将连续输入的字符数字转换成相应的int类型 f=pop(opnd); push(opnd,(f*10+(c-4
11、8); else push(opnd,c-48);/将单个的字符数字转换生相应的int类型 flag=1; c=getchar(); else flag=0; switch(precede(gettop1(*optr),c) case : theta=pop1(optr); l=pop(opnd); a=pop(opnd);/从栈中取得计算元素 push(opnd,operate(a,theta,l);/将元素计算后压入栈中 break;/switch/if/while return pop(opnd);8、为了更加丰富本课程设计特增加注册与登录函数(1)登录函数,其中包含原始密码“xnxy2
12、008”elemtype denglu( )/登录(以一个比较函数来核对其身份)elemtype i, g=3;while(g) printf(please enter your password .n); for(i=0;i9;i+) di=getch(); if(di!=r) printf(*); else di=0;break; if(strcmp(b,d)=0|(k=1&strcmp(c,d)=0) return 1; break; g-; return 0;(2)注册函数elemtype zhuce( )/注册以一个比较函数来确定密码elemtype i; printf(tttple
13、sae enter you uername!n);scanf(%s,h);do printf(tttplease enter your password:n); /输入密码被函数getch吸收到数组以*号形式显示出来 for(i=0;i9;i+) ci=getch(); if(ci!=r) printf(*); else ci=0; break; printf(ntttplease enter your password again!n); for(i=0;ibase=(elemtype*)malloc(stack_size*sizeof(elemtype); if(!s-base) retu
14、rn error ; s-top=s-base; s-stacksize=stack_size; return ok;elemtype initstack1(linklist1 s)/初始化栈 s-base=(char*)malloc(stack_size*sizeof(char); if(!s-base) return error ; s-top=s-base; s-stacksize=stack_size; return ok;elemtype gettop(sqstack s)/取栈顶元素 elemtype e; if(s.top=s.base) printf(no number lef
15、t !); return error; e=*s.top; return e; char gettop1(sqstack1 s)/取栈顶元素 char e; if(s.top=s.base) printf(no number left !); return error; e=*s.top; return e; elemtype push(linklist s,elemtype e)/进栈 if(s-top-s-base=s-stacksize) s-base=(elemtype*)realloc(s-base,(s-stacksize+stack_increasement)*sizeof(el
16、emtype); if(!(s-base) return 0; s-top=s-base+s-stacksize; s-stacksize+=stack_increasement; *(+s-top)=e; return 1;elemtype push1(linklist1 s,char e)/进栈 if(s-top-s-base=s-stacksize) s-base=(char*)realloc(s-base,(s-stacksize+stack_increasement)*sizeof(char); if(!(s-base) return 0; s-top=s-base+s-stacks
17、ize; s-stacksize+=stack_increasement; *(+s-top)=e; return 1;elemtype pop(linklist s)/去栈顶元素 elemtype e; if(s-top=s-base) return error; else e=*s-top; s-top-; return e;char pop1(linklist1 s)/去栈顶元素 char e; if(s-top=s-base) return error; else e=*s-top; s-top-; return e;char precede(char top,char c)/top为
18、操作符的栈顶元素,c为当前输入操作符,若c的优先级大于top返回,c与top构成括号匹配返回= char result; switch(c) case #:result=;break; case +: case -:if(top=#|top=() result=;break; case *: case /:if(top=*|top=/)result=; else result=;break; case (: result=;break; default: printf(the operater is out of band.n); / switchreturn result; elemtype
19、 operate(elemtype a,char theta,elemtype b)/计算式的计算 elemtype result; switch(theta) case +: result=a+b;break; case -: result=a-b;break; case *: result=a*b;break; case /:if(b=0)/特殊计算特殊处理 printf(分母为0,the result is errorn); result=0; else result=a/b;break;default: printf(nthe operater is wrong.n); return
20、result;elemtype in(char c) /判断输入字符是否为运算符,返回1,则c为操作符,返回0则c不是操作符 char p8=+-*/()#; elemtype i=0; while(pi!=0) if(pi=c) return 1; i+; return 0;elemtype evaluate(linklist opnd,linklist1 optr) elemtype flag=0;/当flag为0时表示上一个输入的是字符符号,当其为1时表示上一个输入的是数字字符 elemtype a,l,f; char theta,c,e; c=getchar(); while(c!=#
21、|gettop1(*optr)!=#)/当不是终止符或者是开始符时继续 if(!in(c)/c若为操作数则入opnd栈 if(flag=1)/将连续输入的字符数字转换成相应的int类型 f=pop(opnd); push(opnd,(f*10+(c-48); else push(opnd,c-48);/将单个的字符数字转换生相应的int类型 flag=1; c=getchar(); else flag=0; switch(precede(gettop1(*optr),c) case : theta=pop1(optr); l=pop(opnd); a=pop(opnd);/从栈中取得计算元素
22、push(opnd,operate(a,theta,l);/将元素计算后压入栈中 break;/switch/if/while return pop(opnd); elemtype zhuce( )/注册以一个比较函数来确定密码elemtype i; printf(tttplesae enter you uername!n);scanf(%s,h);do printf(tttplease enter your password:n); /输入密码被函数getch吸收到数组以*号形式显示出来 for(i=0;i9;i+) ri=getch(); if(ri!=r) printf(*); else
23、 ri=0; break; printf(ntttplease enter your password again!n); for(i=0;i9;i+) di=getch(); if(di!=r) printf(*); else di=0; break; if(strcmp(r,d)=0) printf(ntttcongratulations!ntwelcome %s !n,h); k=1; return 1; break; else printf(tttplesae try again!n);while(1);elemtype denglu( )/登录(以一个比较函数来核对其身份)elemt
24、ype i, g=3;while(g) printf(please enter your password .n); for(i=0;i9;i+) di=getch(); if(di!=r) printf(*); else di=0;break; if(strcmp(b,d)=0|(k=1&strcmp(r,d)=0)/是原始密码或者已经注册 return 1; break; else printf(nterror input !nttt); g-; return 0;void main() elemtype n,m=0,flag=3,result;sqstack opnd0;sqstack1
25、 optr0; linklist opnd;/操作数栈 linklist1 optr;/操作符栈opnd=&opnd0; optr=&optr0; do printf(please make a choice !ntt 0:注册;t1:登录。); printf(n); scanf(%d,&n); printf(n); if(n=0) m=zhuce( ); else if(n=1) m=denglu( ); else flag-; printf(error iuput !); while(flag&!m); getchar(); while(m=1) initstack1(optr); ini
26、tstack(opnd); push1(optr,#); printf(n*n); printf(nnn please input the 运算表达式,以#结尾nnn); printf(n*n); result=evaluate(opnd,optr); printf(ntthe result is %dnn,result); getchar(); 四、使用说明:(一)登陆界面1:登陆界面2:(二)输入运算表达式可能结果1:可能结果2:五、调试分析说明:1、输入的操作数和操作码由于是字符串类型的,在原设计中实现的操作都是对个位数实现的。由于仅是对个位数的运算,实用性不大,故在后来的设计中,通过一
27、个标志flag实现了标志操作数的连续输入的判别,继而实现了多位数的表达式运算。2、本设计的关键是运算符优先级的判断,由于优先级的错判,很容导致结果的运算错误。 要明晰判断当前运算符和运算符栈栈顶元素的先后顺序,这个易出错误。3、在本次设计中充分利用了,栈先进后出的特点。4、该设计的内存分配:初始化栈时,每个栈分配100个内存单元,如果不够用,以后每次可增加10个动态内存单元。5、由于程序比较长,在调试期间,可以再每个调用函数中加上printf语句,通过观察程序的运行过程,理由查找错误,和改进程序。6、程序时间复杂度为o(n);7、该设计,自顶向下,分层设计,将每个功能模块化,简洁明了。8、经验
28、体会:借助debug调试器和数据观察窗口,可以加快找到程序的瑕点9、要注意在算数运算中,除数不能为0,在开始的设计中没有注意到这一点。10、在表达式的运算中,要注意输入的是字符串,应将其转换为相应的整形类型的数据再进行运算。否则将出错。并且应当操作数的出栈顺序,以及相应的运算顺序,先出栈的为第二操作数,第二次出栈的为第一操作数。 11、设计的登录函数和注册函数使得只有在注册或者知道原始密码的情况下才可以登录到操作界面,从而保证了设计的技术权威性。六、特色及改进设想;本程序适用于基础的四则运算,但不是用于像乘方之类的运算,这是他的一个大弊端,为了解决这个问题我们还得继续进行研究。在各个运算处加入
29、之类的运算,调用到数学函数库中的的pow()等函数。为了使得本设计更实用一些,特意设计登录函数及注册函数,如此可以增加本设计的全面性。七、程序的产生该程序是由我们这个团体的所有成员分工合作,辛勤劳动的结果。我们不否认从网上有过摘抄,但是更多的是我们的汗水与对知识的总结。在形成过程中我们先是一起讨论,之后是有人负责密码部分,也有人负责基本函数部分,还有人负责主要函数部分,重要的是有人负责总体的安排与调试。这使得我们学会了团队合作的重要性。坚信:团结就是力量。八、综合设计过程,做出总结;(1)总结人:杨剑(学号:200814160237) 通过这个学期对数据结构的学习,我获益匪浅。特别是在学栈的时
30、候我学的很认真。因而这次课程设计我可以较为轻易的解决。但是这次的课程设计我还是 碰到了几个难题。其一,如何处理栈的构建问题,由于输进去的有数字也有字符所以这里的有一个判断。我起初试图用一个初始函数去解决,因为我认为int型的应该可以容纳字符型的,但是解决不了。其二,就是函数调用时候的地址问题。这次的课程设计中的函数并非全部都得用地址,譬如gettop()函数他就不需要用;而top()函数却得用。这时因为top()函数的改变栈的存储的内容而gettop()则不用。第三,做事得有条理 ,分清主次,有强烈的逻辑性。第四,由于运行环境的问题,我们该程序得加上几个 gerchar()函数,这还是一个不懂
31、的地方,因为对于这个环境(c/c+程序设计学习与试验系统)还是第一次碰到这个问题。总之,这次设计对我的数据结构及c 语言有个综合性的考察,让我对他们了解的更加透彻。并且大大加深了我的我的专业的学习热情。我期待来年的学习使对计算机的了解更加透彻!(2)杨基长(200814160236)经过两个星期的实习,过程曲折可谓一语难尽。在此期间我们也失落过,也曾一度热情高涨。从开始时满富盛激情到最后汗水背后的复杂心情,点点滴滴无不令我回味无长。生活就是这样,汗水预示着结果也见证着收获。劳动是人类生存生活永恒不变的话题。通过实习,我才真正领略到“艰苦奋斗”这一词的真正含义。我想说,设计确实有些辛苦,但苦中也
32、有乐,在如今单一的理论学习中,很少有机会能有实践的机会,但我们可以,而且设计也是一个团队的任务,一起的工作可以让我们有说有笑,相互帮助,配合默契,多少人间欢乐在这里洒下,大学里一年的相处还赶不上这十来天的合作,我感觉我和同学们之间的距离更加近了;我想说,确实很累,但当我们看到自己所做的成果时,心中也不免产生兴奋; 正所谓“三百六十行,行行出状元”。我们同样可以为社会作出我们应该做的一切,这有什么不好?我们不断的反问自己。也许有人不喜欢这类的工作,也许有人认为设计的工作有些枯燥,但我们认为无论干什么,只要人生活的有意义就可。社会需要我们,我们也可以为社会而工作。既然如此,那还有什么必要失落呢?于
33、是我们决定沿着自己的路,执着的走下去。同时我认为我们的工作是一个团队的工作,团队需要个人,个人也离不开团队,必须发扬团结协作的精神。某个人的离群都可能导致导致整项工作的失败。实习中只有一个人知道原理是远远不够的,必须让每个人都知道,否则一个人的错误,就有可能导致整个工作失败。团结协作是我们实习成功的一项非常重要的保证。而这次实习也正好锻炼我们这一点,这也是非常宝贵的。对我们而言,知识上的收获重要,精神上的丰收更加可喜。挫折是一份财富,经历是一份拥有。这次实习必将成为我人生旅途上一个非常美好的回忆!通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。这次课程设计终于顺利完成了!(3)汤友松(200814160230)通过这次四则运算课程设计,我不仅加深了对四则运算的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 地质学地球构造与矿产资源知识点梳理与习题集
- 全新危险废物运输合同
- 市政工程项目风险管理试题及答案
- 金融行业资金流水证明书(8篇)
- 鼓励创新思维实现团队突破计划
- 加强团队合作的仓库管理方案计划
- 有效进行仓库费用预算的方法计划
- 工程经济决策分析题目试题及答案
- 设计行业趋势分析与个人应对策略计划
- 水利水电工程创新策略与试题及答案
- 诉讼文书送达地址确认书
- 一级病原微生物实验室危害评估报告
- 茶叶加工机械与设备(全套524张课件)
- 五年级下册数学课件-4.分数连加、连减和加减混合运算及应用练习 苏教版 (共11张PPT)
- 设备机房出入登记表
- 电脑节能环保证书
- 工程质保金付款申请表格
- 建房界址四邻无争议确认表
- 肝胆外科住院医师规范化培训理论考试(题库)
- 机械设备安装与维修理论教案
- 房屋外立面改造施工组织设计
评论
0/150
提交评论