报告.docx
《报告.docx》由会员分享,可在线阅读,更多相关《报告.docx(25页珍藏版)》请在冰豆网上搜索。
报告
数据结构课程设计
设计报告
学院、系:
理学院数学系
专业:
数学与信息
姓名:
学号:
任课教师:
陆老师
提交日期:
2012、2、12
电子邮箱:
综合题目一
猫抓老鼠的模拟
【目录】
1.题目与内容叙述………………………………………3
2.数据结构描述…………………………………………4
3.算法描述
1、主函数与整体架构………………………………6
2、分块函数功能描述………………………………7
4.调试……………………………………………………11
5.小结……………………………………………………13
第一部分题目与内容叙述
题目:
在一个迷宫内,猫正在追老鼠,猫总是选择在迷宫中到老鼠最近的路线走,而老鼠也选择远离猫的路线逃离。
模拟猫抓老鼠的动态过程。
要求
1)设计一个迷宫;猫、老鼠的位置随机生成;
2)猫、老鼠每移动一次,都重新计算最短路径。
3)分别模拟猫的速度大于老鼠、猫的速度等于老鼠两种情形。
4)迷宫可用数组表示,最短路径可用队列表示。
思路叙述:
通过审题,计划主要运用“图”的知识,用“邻接表”的存储方法实现,用“单链表”存储路径。
迷宫用二维数组表示,通过坐标惟一标识每个位置。
在程序中设置好的固定迷宫如下图所示
定义
ALGraph;图类型、无向图相当于迷宫路线简图
AdjList[MAXV];邻接表类型
LinkList;非绝路信息图单链表
第二部分数据结构描述
classInfoType
{public:
intiv;
intloc1,loc2;
};
InfoType(记录顶点中的其他信息)
//iv=0时非绝路;iv=1是绝路;
//loc1和loc2记录在迷宫中的位置(横纵坐标);
typedefstruct
{
intno;
InfoTypeinfo;
}Vertex;
Vertex(矩阵中每个点的信息)
//顶点编号;
typedefstructANode
intadjvex;
StructANode*nextrac;InfoTypeinfo;
}ArcNode;
//顶点中的其他信息;
ArcNode(弧结点类型)
//该弧的终点编号
//指向下一条弧的指针
//该弧重点位置的相关信息
typedefstructVNode
inthno;
Vertexdata;
ArcNode*firstrac;
}VNode;
VNode(表头结点类型)
//该顶点的弧边数
//该顶点信息
//指向第一条弧
typedefVNodeAdjList[MAXV];
邻接表类型
AdjListadjlist;
intn,e;
}ALGraph;
ALGraph(图类型。
无向图相当于迷宫路线简图)
//邻接表
//图中的顶点数和边数
typedefstructLNode
InfoTypedata;
structLNode*next;
}LinkList;
LinkList(非绝路信息图单链表)
//该位置的信息
//指向下一结点的指针
intmano1;
intmano2;
intsamefl;
}intv;
//该结点编号
//图中母亲结点编号
//轨迹队列中母亲结点编号
//队列点间同层信息
【图示】
ALGraphadjlistne
hnodata*firstrac
1noinfoadjvexinfo
2
3
……
第三部分算法描述
1、主函数与整体架构
过程简述:
①系统提示输入“请按上图数字,依次输入猫和老鼠的初始坐标,及出口位置”;
②输入猫坐标cs1cs2,调用translatecu1函数,转化为图编号;
③输入老鼠坐标ms1ms2,调用translatecu1函数,转化为图编号;
④输入出口坐标ex1ex2,调用translatecu1函数,转化为图编号;
⑤系统提示输入“请依次输入猫和老鼠的速度(最好不超过3)”;
⑥依次输入猫的速度sp1,老鼠速度sp2;
⑦调用CatchARun函数,显示路径和结果。
变量定义:
猫的坐标:
坐标cs1cs2
图编号cs(cs=translatecu1(cs1,cs2,map))
老鼠的坐标:
坐标ms1ms2
图编号ms(ms=translatecu1(ms1,ms2,map))
出口的坐标:
坐标ex1ex2
图编号ex(ex=translatecu1(ex1,ex2,map))
速度:
猫sp1
老鼠sp2
运动路径:
猫queue1[M*N]
老鼠queue2[M*N]
PathBFS
函数的调用:
newloc(含有重载)
CatchARun(计算结果,显示路径)
main
CreatALG(创建图)
translatecu1(将坐标转换为图编号)
2.分块函数功能描述
(一)创建图
ALGraph*CreateALG(intmg[M+1][N+1],LinkList*&map2)
主要变量定义:
ALGraph*a
ArcNode*p
主要设计步骤:
※for(intm=1;m<=M;m++)
for(intn=1;n<=N;n++)
if(mg[m][n]==0)//如果坐标为(m,n)的位置为空,
a->adjlist[l].data.info.loc1=m;
a->adjlist[l].data.info.loc2=n;
a->adjlist[l].hno=0;
a->adjlist[l].firstrac=NULL;
for(intdi=0;di<4;di++)//选择上下左右的入口
switch(di)
case0:
f=m-1;g=n;break;//上
case1:
f=m;g=n+1;break;//右
case2:
f=m+1;g=n;break;//下
case3:
f=m;g=n-1;break;//左
}
……………………
※for(l=0;l※for(l=0;l<=k;l++)//判断是否为绝路点※for(l=0;l{p=a->adjlist[l].firstrac;while(p!=NULL){p->info.iv=a->adjlist[p->adjvex].data.info.iv;p=p->nextrac;}}(2)广度优先函数intPathBFS(ALGraph*G,intv,intz,int&rear,intvqueue[MAXV])v为起点位置编号、z为目标位置编号、寻找两点间最短路径、返回长度和路径{ArcNode*p;intfront=0,temp=0;rear=0;intvisited[MAXV];intw,i,h=0;//h为记录路径长度for(i=0;in;i++)visited[i]=0;visited[v]=1;queue[rear].samefl=-2;rear=(rear+1)%MAXV;queue[rear].no=v;queue[rear].mano2=0;queue[rear].samefl=-1;while(queue[rear].no!=z&&front!=rear)//广度遍历、每层图点入列{front=(front+1)%MAXV;w=queue[front].no;//图中母亲节点编号变量p=G->adjlist[w].firstrac;if(front<3||queue[queue[front].mano2].samefl!=queue[queue[(front-1)%MAXV].mano2].samefl)h++;while(p!=NULL&&queue[rear].no!=z){if(visited[p->adjvex]==0){visited[p->adjvex]=1;rear=(rear+1)%MAXV;queue[rear].no=p->adjvex;queue[rear].mano1=w;queue[rear].mano2=front;queue[rear].samefl=h;}p=p->nextrac;}}if(front!=rear)//有路径到达returnh;elsereturn-1;} (3)坐标转换为图编号inttranslatecu1(intc1,intc2,ALGraph*map){intp=0;for(inti=0;in;i++)if(map->adjlist[i].data.info.loc1==c1&&map->adjlist[i].data.info.loc2==c2){p=1;returni;break;}if(p==1){cout<<"theadressisnotexist,pleaseinputanother!";return-1;}}(四)动态位置intnewloc(intrear,intvqueue[M*N],intsp)返回每秒的新位置队列编号{inte=rear,j=e,temp,i,e1=e,h=0;while(j>1){if(h>1)e1=e;e=j;for(i=sp;i>0;i--)//后退速度的步数{if(e>1)e=queue[e].mano2;elsebreak;}temp=j;j=e;e=temp;h++;if(h==1)i=sp;}for(h=sp-i;h>0;h--)//翻转过来e1=queue[e1].mano2;returne1;}(5)抓捕函数voidCatchARun(ALGraph*map,LinkList*map2,intcs,intms,intex,intsp1,intsp2,intvqueue1[M*N],intvqueue2[M*N])主要变量定义:intrear1,rear2,boolv=1,i,j,k,j1,temp;inte1,e2,e,e0;//boolv为判断是否抓住老鼠逻辑变量默认值为1(没抓到正在捕抓)intcsl=PathBFS(map,cs,ex,rear1,queue1);intmsl=PathBFS(map,ms,ex,rear2,queue2);主要设计结构:if(msl==-1||msl==0||csl==-1)boolv=-1;Elseif(queue1[rear1].samefl>sp1)…………Else…………if(boolv==0)//递归出口抓住输出…………elseif(boolv==-1)//老鼠到达出口或者开始位置是隔离的…………elseif(msl/sp2<=csl/sp1)//老鼠可安全逃向出口…………Else//无法安全到达出口跑向最远离猫的非绝路点………… 第四部分调试初始界面 特殊情况验证:猫和老鼠同起点猫和老鼠都从(1,1)位置开始,出口在(1,8),速度都为1时,;老鼠被抓住。 特殊情况验证:老鼠初始位置在出口处猫在(1,1),老鼠在(1,8),出口为(1,8),速度均为1,老鼠能逃走。改变速度猫(1,1),老鼠(1,4),出口(1,8),猫速度2,老鼠速度1,老鼠被抓住第五部分总结经过自己的学习探索,以及向专业人士的咨询,终于完成了此次课程设计,收获颇丰。通过请教、编辑、调试,毋庸置疑使我在理论、操作方面都有所提高,学会了如何将所学知识应用到实际,体会到C语言的强大和数据结构的神奇之处。但由于所学知识有限、编程经验不足,课程设计进行中遭遇错误、卡壳、无从下手等困难,但正由此可见,实践对于学习数据结构的重要性。因此,为了在今后必要时能熟练使用C++语言,还需时常的学习和长久的应用训练,使之成为自己的一项本领。根据我在实习中遇到得问题,我将在以后的学习过程中注意以下几点:1、认真上好专业实验课,多在实践中锻炼自己。2、写程序的过程中要考虑周到,严密。3、在做设计的时候要有信心,有耐心,切勿浮躁。4、认真的学习课本知识,掌握课本中的知识点,并在此基础上学会灵活运用。5、在课余时间里多写程序,熟练掌握在调试程序的过程中所遇到的常见错误,以便能节省调试程序的时间。 综合题目二复杂表达式的求值 【目录】1.题目与内容叙述………………………………………152.栈的数据结构描述……………………………………163.算法设计1、算符的优先级比较函数Compare……………………172、确定如何入栈函数evaluate……………………183、主函数及分模块介绍……………………………19四.调试……………………………………………………20五.小结……………………………………………………22 第一部分题目与内容叙述问题描述输入一个含有运算符和运算函数的表达式,计算其结果。要求1)以字符串方式输入一个复杂的表达式;2)利用栈,根据各运算符的优先度进行数值计算,显示结果3)循环回1),继续下个表达式的输入。功能扩展:显示计算过程 第二部分栈的数据结构描述栈的抽象数据类型定义ADTSqStack{数据对象:D={ai|ai∈ElemSet,i=1,2,3……,n,n≥0}数据关系:R1={|ai-1,ai∈D,i=1,2,3,……,n}约定其中ai端为栈底,an端为栈顶操作集合:(1)voidInitStack1(SqStack1&S1);//声明栈建立函数(2)voidInitStack2(SqStack2&S2);//声明栈建立函数(3)voidevaluate(SqStack1&S1,SqStack2&S2);//确定如何入栈函数(4)voidPush1(SqStack1&S1,chare);//声明入栈函数(5)voidPush2(SqStack2&S2,floate);//声明入压栈函数(6)charGetTop1(SqStack1&S1);//声明取栈顶元素函数(7)floatGetTop2(SqStack2&S2);//声明取栈顶元素函数(8)charPop1(SqStack1&S1);//声明出栈函数(9)floatPop2(SqStack2&S2);//声明出栈函数(10)charCompare(charm,charn);//声明比较函数(11)floatOperate(floata,charrheta,floatb);//声明运算函数(12)voidDispStack1(SqStack1&S1);//从栈底到栈顶依次输出各元素(13)voidDispStack2(SqStack2&S2);//从栈底到栈顶依次输出各元素}ADTSqStack 第三部分算法设计1、算符的优先级比较函数Compare(charm,charn)算法的基本思想:通过已知的算符间的优先关系写出算符的优先级算法。任意两个相继出现的算符c1和c2之间的优先关系至多是下面3种关系之一:c1c1=c2c1的优先权等于c2c1>c2c1的优先权高于c2算法步骤:Step1:如果输入符号为“+”或“-”1.1如果栈顶元素为“(”、“#”,此时栈顶符号优先级低,返回“<”1.2否则,栈顶符号优先级高,返回“>”Step2:如果输入符号为“*”或“/”2.1如果栈顶元素为“)”、“*”、“/”,此时栈顶符号优先级高,返回“>”2.2否则,栈顶符号优先级低,返回“<”Step3:如果输入符号为“(”,则直接返回“<”Step4:如果输入符号为“)”4.1如果栈顶元素为“(”,此时优先级同,返回“=”4.2否则,栈顶符号优先级高,返回“>”Step5:输入符号为其他5.1栈顶元素为“#”,此时优先级同,返回“=”5.2否则,栈顶符号优先级高,返回“>” 2、确定如何入栈函数evaluate(SqStack1&S1,SqStack2&S2)算法的基本思想:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;(2)依次读入表达式中每个字符,若是操作数则进运算数栈,若是运算符则和运算符栈的栈顶运算符比较优先后作相应操作,直至整个表达式求值完毕(即运算符的栈顶元素和当前读入的字符均为“#”)。算法步骤:Step1:将‘#’入栈,作为低级运算符Step2:输入不含变量的表达式(以#结束!)Step3:如果c!='#'||GetTop1(S1)!='#'3.1如果输入的字符如果不是运算符号,则继续输入直到输入的是运算符为止,将非运算符转换成浮点数3.2如果输入的是运算符a、遇到运算符,则将之前输入的操作数进栈b、比较运算符的优先级1)栈顶元素优先级低,则入栈且继续输入2)栈顶元素优先级相等,脱括号并接收下一字符3)栈顶元素优先级高,则退栈并将运算结果入栈Step4:显示表达式最终结果 3、主函数及分模块介绍程序包含三个模块(1)主程序模块,其中主函数为voidmain{输入表达式;根据要求进行转换并求值;输出结果;}(2)表达式求值模块——实现具体求值。(3)表达式转换模块——实现转换。 各个函数之间的调用关系 第四部分调试初始界面验证简单加减乘除表达式:输入1.0+2.0#结果正确验证混合运算表达式:输入:1+2*4#结果正确特殊情况验证:输入:3/0显示输入错误提示第五部分总结1.结构分析:栈中的数据节点是通过数组来存储的。因为在C语言中数组是用下标从零开始的,因此我们在调用他们的数据是要特别注意。指针变量的值要么为空(NULL),不指向任何结点;要么其值为非空,即它的值是一个结点的存储地址。注意,当P为空值时,则它不指向任何结点,此时不能通过P来访问结点,否则会引起程序错误。如果输入的数字不符合题目要求,则会产生错误结果。2.算法的时空分析:时间和空间性能分析:时间上,对于含n个字符的表达式,无论是对其进行合法性检测还是对其进行入栈出栈操作n次,因此其时间复杂度为O(n)。空间上,由于是用数组来存储输入的表达式,用栈来存储运算中的数据和运算符,而栈的本质也用到的数组,数组在定义时必须确定其大小。在不知表达式长度的情况下确定数组的长度确非易事,此时极易造成空间的浪费,因此空间性能不是很好。不足之处:(1)用栈的结构来解决表达式的求值,首先要解决的问题是如何将人们习惯书写的表达式转换成计算机容易处理的表达式。开始有些茫然,后来通过结合课本和同学的帮助完成了该课题。(2)对一些看似简单的东西掌握不够熟练,比如由于函数的调用参数问题不熟而造成了调试的困难。对于语法的掌握也欠缺成熟,需要进一步掌握。(3)栈的结构理解不够清晰,造成了设计程序时理不清头绪,需要对数据结构有更深层次的理解。 基础题运行截图1.链表2.二叉树3.图
※for(l=0;l<=k;l++)//判断是否为绝路点
※for(l=0;l{p=a->adjlist[l].firstrac;while(p!=NULL){p->info.iv=a->adjlist[p->adjvex].data.info.iv;p=p->nextrac;}}(2)广度优先函数intPathBFS(ALGraph*G,intv,intz,int&rear,intvqueue[MAXV])v为起点位置编号、z为目标位置编号、寻找两点间最短路径、返回长度和路径{ArcNode*p;intfront=0,temp=0;rear=0;intvisited[MAXV];intw,i,h=0;//h为记录路径长度for(i=0;in;i++)visited[i]=0;visited[v]=1;queue[rear].samefl=-2;rear=(rear+1)%MAXV;queue[rear].no=v;queue[rear].mano2=0;queue[rear].samefl=-1;while(queue[rear].no!=z&&front!=rear)//广度遍历、每层图点入列{front=(front+1)%MAXV;w=queue[front].no;//图中母亲节点编号变量p=G->adjlist[w].firstrac;if(front<3||queue[queue[front].mano2].samefl!=queue[queue[(front-1)%MAXV].mano2].samefl)h++;while(p!=NULL&&queue[rear].no!=z){if(visited[p->adjvex]==0){visited[p->adjvex]=1;rear=(rear+1)%MAXV;queue[rear].no=p->adjvex;queue[rear].mano1=w;queue[rear].mano2=front;queue[rear].samefl=h;}p=p->nextrac;}}if(front!=rear)//有路径到达returnh;elsereturn-1;} (3)坐标转换为图编号inttranslatecu1(intc1,intc2,ALGraph*map){intp=0;for(inti=0;in;i++)if(map->adjlist[i].data.info.loc1==c1&&map->adjlist[i].data.info.loc2==c2){p=1;returni;break;}if(p==1){cout<<"theadressisnotexist,pleaseinputanother!";return-1;}}(四)动态位置intnewloc(intrear,intvqueue[M*N],intsp)返回每秒的新位置队列编号{inte=rear,j=e,temp,i,e1=e,h=0;while(j>1){if(h>1)e1=e;e=j;for(i=sp;i>0;i--)//后退速度的步数{if(e>1)e=queue[e].mano2;elsebreak;}temp=j;j=e;e=temp;h++;if(h==1)i=sp;}for(h=sp-i;h>0;h--)//翻转过来e1=queue[e1].mano2;returne1;}(5)抓捕函数voidCatchARun(ALGraph*map,LinkList*map2,intcs,intms,intex,intsp1,intsp2,intvqueue1[M*N],intvqueue2[M*N])主要变量定义:intrear1,rear2,boolv=1,i,j,k,j1,temp;inte1,e2,e,e0;//boolv为判断是否抓住老鼠逻辑变量默认值为1(没抓到正在捕抓)intcsl=PathBFS(map,cs,ex,rear1,queue1);intmsl=PathBFS(map,ms,ex,rear2,queue2);主要设计结构:if(msl==-1||msl==0||csl==-1)boolv=-1;Elseif(queue1[rear1].samefl>sp1)…………Else…………if(boolv==0)//递归出口抓住输出…………elseif(boolv==-1)//老鼠到达出口或者开始位置是隔离的…………elseif(msl/sp2<=csl/sp1)//老鼠可安全逃向出口…………Else//无法安全到达出口跑向最远离猫的非绝路点………… 第四部分调试初始界面 特殊情况验证:猫和老鼠同起点猫和老鼠都从(1,1)位置开始,出口在(1,8),速度都为1时,;老鼠被抓住。 特殊情况验证:老鼠初始位置在出口处猫在(1,1),老鼠在(1,8),出口为(1,8),速度均为1,老鼠能逃走。改变速度猫(1,1),老鼠(1,4),出口(1,8),猫速度2,老鼠速度1,老鼠被抓住第五部分总结经过自己的学习探索,以及向专业人士的咨询,终于完成了此次课程设计,收获颇丰。通过请教、编辑、调试,毋庸置疑使我在理论、操作方面都有所提高,学会了如何将所学知识应用到实际,体会到C语言的强大和数据结构的神奇之处。但由于所学知识有限、编程经验不足,课程设计进行中遭遇错误、卡壳、无从下手等困难,但正由此可见,实践对于学习数据结构的重要性。因此,为了在今后必要时能熟练使用C++语言,还需时常的学习和长久的应用训练,使之成为自己的一项本领。根据我在实习中遇到得问题,我将在以后的学习过程中注意以下几点:1、认真上好专业实验课,多在实践中锻炼自己。2、写程序的过程中要考虑周到,严密。3、在做设计的时候要有信心,有耐心,切勿浮躁。4、认真的学习课本知识,掌握课本中的知识点,并在此基础上学会灵活运用。5、在课余时间里多写程序,熟练掌握在调试程序的过程中所遇到的常见错误,以便能节省调试程序的时间。 综合题目二复杂表达式的求值 【目录】1.题目与内容叙述………………………………………152.栈的数据结构描述……………………………………163.算法设计1、算符的优先级比较函数Compare……………………172、确定如何入栈函数evaluate……………………183、主函数及分模块介绍……………………………19四.调试……………………………………………………20五.小结……………………………………………………22 第一部分题目与内容叙述问题描述输入一个含有运算符和运算函数的表达式,计算其结果。要求1)以字符串方式输入一个复杂的表达式;2)利用栈,根据各运算符的优先度进行数值计算,显示结果3)循环回1),继续下个表达式的输入。功能扩展:显示计算过程 第二部分栈的数据结构描述栈的抽象数据类型定义ADTSqStack{数据对象:D={ai|ai∈ElemSet,i=1,2,3……,n,n≥0}数据关系:R1={|ai-1,ai∈D,i=1,2,3,……,n}约定其中ai端为栈底,an端为栈顶操作集合:(1)voidInitStack1(SqStack1&S1);//声明栈建立函数(2)voidInitStack2(SqStack2&S2);//声明栈建立函数(3)voidevaluate(SqStack1&S1,SqStack2&S2);//确定如何入栈函数(4)voidPush1(SqStack1&S1,chare);//声明入栈函数(5)voidPush2(SqStack2&S2,floate);//声明入压栈函数(6)charGetTop1(SqStack1&S1);//声明取栈顶元素函数(7)floatGetTop2(SqStack2&S2);//声明取栈顶元素函数(8)charPop1(SqStack1&S1);//声明出栈函数(9)floatPop2(SqStack2&S2);//声明出栈函数(10)charCompare(charm,charn);//声明比较函数(11)floatOperate(floata,charrheta,floatb);//声明运算函数(12)voidDispStack1(SqStack1&S1);//从栈底到栈顶依次输出各元素(13)voidDispStack2(SqStack2&S2);//从栈底到栈顶依次输出各元素}ADTSqStack 第三部分算法设计1、算符的优先级比较函数Compare(charm,charn)算法的基本思想:通过已知的算符间的优先关系写出算符的优先级算法。任意两个相继出现的算符c1和c2之间的优先关系至多是下面3种关系之一:c1c1=c2c1的优先权等于c2c1>c2c1的优先权高于c2算法步骤:Step1:如果输入符号为“+”或“-”1.1如果栈顶元素为“(”、“#”,此时栈顶符号优先级低,返回“<”1.2否则,栈顶符号优先级高,返回“>”Step2:如果输入符号为“*”或“/”2.1如果栈顶元素为“)”、“*”、“/”,此时栈顶符号优先级高,返回“>”2.2否则,栈顶符号优先级低,返回“<”Step3:如果输入符号为“(”,则直接返回“<”Step4:如果输入符号为“)”4.1如果栈顶元素为“(”,此时优先级同,返回“=”4.2否则,栈顶符号优先级高,返回“>”Step5:输入符号为其他5.1栈顶元素为“#”,此时优先级同,返回“=”5.2否则,栈顶符号优先级高,返回“>” 2、确定如何入栈函数evaluate(SqStack1&S1,SqStack2&S2)算法的基本思想:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;(2)依次读入表达式中每个字符,若是操作数则进运算数栈,若是运算符则和运算符栈的栈顶运算符比较优先后作相应操作,直至整个表达式求值完毕(即运算符的栈顶元素和当前读入的字符均为“#”)。算法步骤:Step1:将‘#’入栈,作为低级运算符Step2:输入不含变量的表达式(以#结束!)Step3:如果c!='#'||GetTop1(S1)!='#'3.1如果输入的字符如果不是运算符号,则继续输入直到输入的是运算符为止,将非运算符转换成浮点数3.2如果输入的是运算符a、遇到运算符,则将之前输入的操作数进栈b、比较运算符的优先级1)栈顶元素优先级低,则入栈且继续输入2)栈顶元素优先级相等,脱括号并接收下一字符3)栈顶元素优先级高,则退栈并将运算结果入栈Step4:显示表达式最终结果 3、主函数及分模块介绍程序包含三个模块(1)主程序模块,其中主函数为voidmain{输入表达式;根据要求进行转换并求值;输出结果;}(2)表达式求值模块——实现具体求值。(3)表达式转换模块——实现转换。 各个函数之间的调用关系 第四部分调试初始界面验证简单加减乘除表达式:输入1.0+2.0#结果正确验证混合运算表达式:输入:1+2*4#结果正确特殊情况验证:输入:3/0显示输入错误提示第五部分总结1.结构分析:栈中的数据节点是通过数组来存储的。因为在C语言中数组是用下标从零开始的,因此我们在调用他们的数据是要特别注意。指针变量的值要么为空(NULL),不指向任何结点;要么其值为非空,即它的值是一个结点的存储地址。注意,当P为空值时,则它不指向任何结点,此时不能通过P来访问结点,否则会引起程序错误。如果输入的数字不符合题目要求,则会产生错误结果。2.算法的时空分析:时间和空间性能分析:时间上,对于含n个字符的表达式,无论是对其进行合法性检测还是对其进行入栈出栈操作n次,因此其时间复杂度为O(n)。空间上,由于是用数组来存储输入的表达式,用栈来存储运算中的数据和运算符,而栈的本质也用到的数组,数组在定义时必须确定其大小。在不知表达式长度的情况下确定数组的长度确非易事,此时极易造成空间的浪费,因此空间性能不是很好。不足之处:(1)用栈的结构来解决表达式的求值,首先要解决的问题是如何将人们习惯书写的表达式转换成计算机容易处理的表达式。开始有些茫然,后来通过结合课本和同学的帮助完成了该课题。(2)对一些看似简单的东西掌握不够熟练,比如由于函数的调用参数问题不熟而造成了调试的困难。对于语法的掌握也欠缺成熟,需要进一步掌握。(3)栈的结构理解不够清晰,造成了设计程序时理不清头绪,需要对数据结构有更深层次的理解。 基础题运行截图1.链表2.二叉树3.图
p=a->adjlist[l].firstrac;
while(p!
=NULL)
p->info.iv=a->adjlist[p->adjvex].data.info.iv;
p=p->nextrac;
(2)广度优先函数
intPathBFS(ALGraph*G,intv,intz,int&rear,intvqueue[MAXV])
v为起点位置编号、z为目标位置编号、寻找两点间最短路径、返回长度和路径
{ArcNode*p;
intfront=0,temp=0;rear=0;
intvisited[MAXV];
intw,i,h=0;//h为记录路径长度
for(i=0;in;i++)visited[i]=0;
visited[v]=1;
queue[rear].samefl=-2;rear=(rear+1)%MAXV;
queue[rear].no=v;queue[rear].mano2=0;queue[rear].samefl=-1;
while(queue[rear].no!
=z&&front!
=rear)//广度遍历、每层图点入列
front=(front+1)%MAXV;
w=queue[front].no;//图中母亲节点编号变量
p=G->adjlist[w].firstrac;
if(front<3||queue[queue[front].mano2].samefl!
=queue[queue[(front-1)%MAXV].mano2].samefl)
h++;
=NULL&&queue[rear].no!
=z)
{if(visited[p->adjvex]==0)
visited[p->adjvex]=1;rear=(rear+1)%MAXV;
queue[rear].no=p->adjvex;
queue[rear].mano1=w;
queue[rear].mano2=front;
queue[rear].samefl=h;
if(front!
=rear)//有路径到达
returnh;
else
return-1;
(3)坐标转换为图编号
inttranslatecu1(intc1,intc2,ALGraph*map)
{intp=0;
for(inti=0;in;i++)
if(map->adjlist[i].data.info.loc1==c1&&map->adjlist[i].data.info.loc2==c2)
p=1;
returni;
break;
if(p==1)
cout<<"theadressisnotexist,pleaseinputanother!
";
(四)动态位置
intnewloc(intrear,intvqueue[M*N],intsp)
返回每秒的新位置队列编号
inte=rear,j=e,temp,i,e1=e,h=0;
while(j>1)
if(h>1)
e1=e;
e=j;
for(i=sp;i>0;i--)//后退速度的步数
if(e>1)
e=queue[e].mano2;
elsebreak;
temp=j;j=e;e=temp;h++;
if(h==1)
i=sp;
for(h=sp-i;h>0;h--)//翻转过来
e1=queue[e1].mano2;
returne1;
(5)抓捕函数
voidCatchARun(ALGraph*map,LinkList*map2,intcs,intms,intex,intsp1,intsp2,intv
queue1[M*N],intvqueue2[M*N])
intrear1,rear2,boolv=1,i,j,k,j1,temp;
inte1,e2,e,e0;//boolv为判断是否抓住老鼠逻辑变量默认值为1(没抓
到正在捕抓)
intcsl=PathBFS(map,cs,ex,rear1,queue1);
intmsl=PathBFS(map,ms,ex,rear2,queue2);
主要设计结构:
if(msl==-1||msl==0||csl==-1)
boolv=-1;
Else
if(queue1[rear1].samefl>sp1)
…………
if(boolv==0)//递归出口抓住输出
elseif(boolv==-1)//老鼠到达出口或者开始位置是隔离的
elseif(msl/sp2<=csl/sp1)//老鼠可安全逃向出口
Else//无法安全到达出口跑向最远离猫的非绝路点
第四部分调试
初始界面
特殊情况验证:
猫和老鼠同起点
猫和老鼠都从(1,1)位置开始,出口在(1,8),速度都为1时,;老鼠被抓住。
老鼠初始位置在出口处
猫在(1,1),老鼠在(1,8),出口为(1,8),速度均为1,老鼠能逃走。
改变速度
猫(1,1),老鼠(1,4),出口(1,8),猫速度2,老鼠速度1,老鼠被抓住
第五部分总结
经过自己的学习探索,以及向专业人士的咨询,终于完成了此次课程设计,收获颇丰。
通过请教、编辑、调试,毋庸置疑使我在理论、操作方面都有所提高,学会了如何将所学知识应用到实际,体会到C语言的强大和数据结构的神奇之处。
但由于所学知识有限、编程经验不足,课程设计进行中遭遇错误、卡壳、无从下手等困难,但正由此可见,实践对于学习数据结构的重要性。
因此,为了在今后必要时能熟练使用C++语言,还需时常的学习和长久的应用训练,使之成为自己的一项本领。
根据我在实习中遇到得问题,我将在以后的学习过程中注意以下几点:
1、认真上好专业实验课,多在实践中锻炼自己。
2、写程序的过程中要考虑周到,严密。
3、在做设计的时候要有信心,有耐心,切勿浮躁。
4、认真的学习课本知识,掌握课本中的知识点,并在此基础上学会灵活运用。
5、在课余时间里多写程序,熟练掌握在调试程序的过程中所遇到的常见错误,以便能节省调试程序的时间。
综合题目二
复杂表达式的求值
1.题目与内容叙述………………………………………15
2.栈的数据结构描述……………………………………16
3.算法设计
1、算符的优先级比较函数Compare……………………17
2、确定如何入栈函数evaluate……………………18
3、主函数及分模块介绍……………………………19
四.调试……………………………………………………20
五.小结……………………………………………………22
问题描述
输入一个含有运算符和运算函数的表达式,计算其结果。
1)以字符串方式输入一个复杂的表达式;
2)利用栈,根据各运算符的优先度进行数值计算,显示结果
3)循环回1),继续下个表达式的输入。
功能扩展:
显示计算过程
第二部分栈的数据结构描述
栈的抽象数据类型定义
ADTSqStack{
数据对象:
D={ai|ai∈ElemSet,i=1,2,3……,n,n≥0}
数据关系:
R1={|ai-1,ai∈D,i=1,2,3,……,n}
约定其中ai端为栈底,an端为栈顶
操作集合:
(1)voidInitStack1(SqStack1&S1);//声明栈建立函数
(2)voidInitStack2(SqStack2&S2);//声明栈建立函数
(3)voidevaluate(SqStack1&S1,SqStack2&S2);//确定如何入栈函数
(4)voidPush1(SqStack1&S1,chare);//声明入栈函数
(5)voidPush2(SqStack2&S2,floate);//声明入压栈函数
(6)charGetTop1(SqStack1&S1);//声明取栈顶元素函数
(7)floatGetTop2(SqStack2&S2);//声明取栈顶元素函数
(8)charPop1(SqStack1&S1);//声明出栈函数
(9)floatPop2(SqStack2&S2);//声明出栈函数
(10)charCompare(charm,charn);//声明比较函数
(11)floatOperate(floata,charrheta,floatb);//声明运算函数
(12)voidDispStack1(SqStack1&S1);//从栈底到栈顶依次输出各元素
(13)voidDispStack2(SqStack2&S2);//从栈底到栈顶依次输出各元素
}ADTSqStack
第三部分算法设计
1、算符的优先级比较函数Compare(charm,charn)
算法的基本思想:
通过已知的算符间的优先关系写出算符的优先级算法。
任意两个相继出现的算符c1和c2之间的优先关系至多是下面3种关系之一:
c1c1=c2c1的优先权等于c2c1>c2c1的优先权高于c2算法步骤:Step1:如果输入符号为“+”或“-”1.1如果栈顶元素为“(”、“#”,此时栈顶符号优先级低,返回“<”1.2否则,栈顶符号优先级高,返回“>”Step2:如果输入符号为“*”或“/”2.1如果栈顶元素为“)”、“*”、“/”,此时栈顶符号优先级高,返回“>”2.2否则,栈顶符号优先级低,返回“<”Step3:如果输入符号为“(”,则直接返回“<”Step4:如果输入符号为“)”4.1如果栈顶元素为“(”,此时优先级同,返回“=”4.2否则,栈顶符号优先级高,返回“>”Step5:输入符号为其他5.1栈顶元素为“#”,此时优先级同,返回“=”5.2否则,栈顶符号优先级高,返回“>” 2、确定如何入栈函数evaluate(SqStack1&S1,SqStack2&S2)算法的基本思想:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;(2)依次读入表达式中每个字符,若是操作数则进运算数栈,若是运算符则和运算符栈的栈顶运算符比较优先后作相应操作,直至整个表达式求值完毕(即运算符的栈顶元素和当前读入的字符均为“#”)。算法步骤:Step1:将‘#’入栈,作为低级运算符Step2:输入不含变量的表达式(以#结束!)Step3:如果c!='#'||GetTop1(S1)!='#'3.1如果输入的字符如果不是运算符号,则继续输入直到输入的是运算符为止,将非运算符转换成浮点数3.2如果输入的是运算符a、遇到运算符,则将之前输入的操作数进栈b、比较运算符的优先级1)栈顶元素优先级低,则入栈且继续输入2)栈顶元素优先级相等,脱括号并接收下一字符3)栈顶元素优先级高,则退栈并将运算结果入栈Step4:显示表达式最终结果 3、主函数及分模块介绍程序包含三个模块(1)主程序模块,其中主函数为voidmain{输入表达式;根据要求进行转换并求值;输出结果;}(2)表达式求值模块——实现具体求值。(3)表达式转换模块——实现转换。 各个函数之间的调用关系 第四部分调试初始界面验证简单加减乘除表达式:输入1.0+2.0#结果正确验证混合运算表达式:输入:1+2*4#结果正确特殊情况验证:输入:3/0显示输入错误提示第五部分总结1.结构分析:栈中的数据节点是通过数组来存储的。因为在C语言中数组是用下标从零开始的,因此我们在调用他们的数据是要特别注意。指针变量的值要么为空(NULL),不指向任何结点;要么其值为非空,即它的值是一个结点的存储地址。注意,当P为空值时,则它不指向任何结点,此时不能通过P来访问结点,否则会引起程序错误。如果输入的数字不符合题目要求,则会产生错误结果。2.算法的时空分析:时间和空间性能分析:时间上,对于含n个字符的表达式,无论是对其进行合法性检测还是对其进行入栈出栈操作n次,因此其时间复杂度为O(n)。空间上,由于是用数组来存储输入的表达式,用栈来存储运算中的数据和运算符,而栈的本质也用到的数组,数组在定义时必须确定其大小。在不知表达式长度的情况下确定数组的长度确非易事,此时极易造成空间的浪费,因此空间性能不是很好。不足之处:(1)用栈的结构来解决表达式的求值,首先要解决的问题是如何将人们习惯书写的表达式转换成计算机容易处理的表达式。开始有些茫然,后来通过结合课本和同学的帮助完成了该课题。(2)对一些看似简单的东西掌握不够熟练,比如由于函数的调用参数问题不熟而造成了调试的困难。对于语法的掌握也欠缺成熟,需要进一步掌握。(3)栈的结构理解不够清晰,造成了设计程序时理不清头绪,需要对数据结构有更深层次的理解。 基础题运行截图1.链表2.二叉树3.图
c1=c2c1的优先权等于c2
c1>c2c1的优先权高于c2
算法步骤:
Step1:
如果输入符号为“+”或“-”
1.1如果栈顶元素为“(”、“#”,此时栈顶符号优先级低,返回“<”
1.2否则,栈顶符号优先级高,返回“>”
Step2:
如果输入符号为“*”或“/”
2.1如果栈顶元素为“)”、“*”、“/”,此时栈顶符号优先级高,返回“>”
2.2否则,栈顶符号优先级低,返回“<”
Step3:
如果输入符号为“(”,则直接返回“<”
Step4:
如果输入符号为“)”
4.1如果栈顶元素为“(”,此时优先级同,返回“=”
4.2否则,栈顶符号优先级高,返回“>”
Step5:
输入符号为其他
5.1栈顶元素为“#”,此时优先级同,返回“=”
5.2否则,栈顶符号优先级高,返回“>”
2、确定如何入栈函数evaluate(SqStack1&S1,SqStack2&S2)
(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;
(2)依次读入表达式中每个字符,若是操作数则进运算数栈,若是运算符则和运算符栈的栈顶运算符比较优先后作相应操作,直至整个表达式求值完毕(即运算符的栈顶元素和当前读入的字符均为“#”)。
将‘#’入栈,作为低级运算符
输入不含变量的表达式(以#结束!
)
如果c!
='#'||GetTop1(S1)!
='#'
3.1如果输入的字符如果不是运算符号,则继续输入直到输入的是运算符为止,将非运算符转换成浮点数
3.2如果输入的是运算符
a、遇到运算符,则将之前输入的操作数进栈
b、比较运算符的优先级
1)栈顶元素优先级低,则入栈且继续输入
2)栈顶元素优先级相等,脱括号并接收下一字符
3)栈顶元素优先级高,则退栈并将运算结果入栈
显示表达式最终结果
3、主函数及分模块介绍
程序包含三个模块
(1)主程序模块,其中主函数为
voidmain{
输入表达式;
根据要求进行转换并求值;
输出结果;
(2)表达式求值模块——实现具体求值。
(3)表达式转换模块——实现转换。
各个函数之间的调用关系
验证简单加减乘除表达式:
输入1.0+2.0#结果正确
验证混合运算表达式:
输入:
1+2*4#结果正确
3/0显示输入错误提示
1.结构分析:
栈中的数据节点是通过数组来存储的。
因为在C语言中数组是用下标从零开始的,因此我们在调用他们的数据是要特别注意。
指针变量的值要么为空(NULL),不指向任何结点;要么其值为非空,即它的值是一个结点的存储地址。
注意,当P为空值时,则它不指向任何结点,此时不能通过P来访问结点,否则会引起程序错误。
如果输入的数字不符合题目要求,则会产生错误结果。
2.算法的时空分析:
时间和空间性能分析:
时间上,对于含n个字符的表达式,无论是对其进行合法性检测还是对其进行入栈出栈操作n次,因此其时间复杂度为O(n)。
空间上,由于是用数组来存储输入的表达式,用栈来存储运算中的数据和运算符,而栈的本质也用到的数组,数组在定义时必须确定其大小。
在不知表达式长度的情况下确定数组的长度确非易事,此时极易造成空间的浪费,因此空间性能不是很好。
不足之处:
(1)用栈的结构来解决表达式的求值,首先要解决的问题是如何将人们习惯书写的表达式转换成计算机容易处理的表达式。
开始有些茫然,后来通过结合课本和同学的帮助完成了该课题。
(2)对一些看似简单的东西掌握不够熟练,比如由于函数的调用参数问题不熟而造成了调试的困难。
对于语法的掌握也欠缺成熟,需要进一步掌握。
(3)栈的结构理解不够清晰,造成了设计程序时理不清头绪,需要对数据结构有更深层次的理解。
基础题运行截图
1.链表
2.二叉树
3.图
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1