《程序设计课程设计》指导书2Word下载.docx
《《程序设计课程设计》指导书2Word下载.docx》由会员分享,可在线阅读,更多相关《《程序设计课程设计》指导书2Word下载.docx(66页珍藏版)》请在冰豆网上搜索。
实现设计中定义的所有数据类型,对每个操作写出伪码算法;
对主程序和其他模块也写出伪码算法(伪码算法的详细程度为按照伪码算法可以在计算机键盘直接输入高级程序设计语言程序);
画出函数的调用关系图。
3.【设计功能的实现】
(用C或C++描述)
//说明:
用C或C++实现代码设计。
4.【实例测试及运行结果】
列出测试结果,包括输入和输出。
测试数据应该完整、严格。
测试分析内容包括:
(1)测试过程中遇到的问题是如何解决的以及对设计与实现的回顾讨论与分析;
(2)算法的时空分析和改进设想;
(3)经验和体会。
5.【实现提示】
使用说明:
说明如何使用该程序,列出每一步的操作步骤。
附录:
列出程序文件名的清单以及必要的带注释的源程序。
心得体会等等。
二.课程设计报告示例——迷宫问题
专业:
班级:
姓名:
学号:
完成日期:
【问题描述】
编制一个求解迷宫通路的程序。
以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。
设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。
求得的通路以三元组(i,j,d)的形式输出,其中:
(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。
如:
对于下列数据的迷宫,输出的一条通路为:
(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2)……
【设计需求及分析】
(1)以二维数组MAZE[M+2][N+2]表示迷宫,其中:
MAZE[0][J]和MAZE[M+1][J](0≤J≤N+1)及MAZE[I][0]和MAZE[I][N+1](0≤I≤M+1)为添加的一圈障碍。
数组中以元素值为0表示通路,1表示障碍。
限定迷宫的大小M,N≤10。
(2)用户以文件的形式输入迷宫的数据:
文件中第一行的数据为迷宫的行数M和列数N;
从第2行至第M+1行(每行N个数)为迷宫值,同一行中的两个数字之间用空白字符相隔。
(3)迷宫的入口位置和出口位置可由用户随时设定。
(4)若设定的迷宫存在通路,则以长方阵形式将迷宫及其通路输出到标准输出文件(即
终端)上,其中,字符“#”表示障碍,字符“*”表示路径上的位置,字符“@”表示“死胡同”,即曾经经过但不能到达出口的位置,其余用空格符表示。
若设定的迷宫不存在通路,则报告相应信息。
(5)本程序只求出一条成功的通路。
然而,只需要对迷宫求解的函数作小量修改,便可求得全部路径。
【设计功能的实现】
(用C或C++语言描述)
说明:
此内容由学生自己设计完成。
提示:
程序应包含的执行命令有:
1)创建迷宫;
2)求解迷宫;
3)输出迷宫的解。
概要设计示例如下:
1.设定栈的抽象数据类型定义为:
ADTstack{
数据对象:
D={ai|ai∈charset,i=1,2,……,n,n≥0}
数据关系:
R1={<
ai-1,ai>
|ai-1,ai∈D,i=2……,n}
基本操作:
InitStack(&
S)
操作结果:
构造一个空栈S。
DestroyStack(&
初始条件:
栈S已存在。
销毁栈S。
ClearStack(&
将S清为空栈。
StackLength(&
返回栈S的长度。
StackEmpty(&
若S为空栈,则返回TRUE,否则返回FALSE。
GetTop(S,&
e)
若栈S不空,则以e返回栈顶元素。
Push(&
S,e)
在栈S的栈顶插入新的栈顶元素e。
Pop(&
S,&
删除S的栈顶元素,并以e返回其值。
StackTraverse(S,visit())
从栈底到栈顶依次对S中的每个元素调用函数visit().
}ADTstack
2.设定迷宫的抽象数据类型为:
ADTmaze{
D={ai,j|ai,j∈{‘’、‘#’、‘@’、‘*’},0≤i≤m+1,0≤j≤n+1,m,n≤10}
R={ROW,COL}
ROW={<
ai-1,j,ai,j>
|ai-1,j,ai,j∈D,i=1,……,m+1,j=0,……,n+1}
COL={<
ai,j-1,ai,j>
|ai,j-1,ai,j∈D,i=0,……,m+1,j=1,……,n+1}
InitMaze(&
M,a,row,col)
二维数组a[row+2][col+2]已存在,其中自第1行至第row+1行、每行中自第1列至第col+1列的元素已有值,并且以值0表示通路,以值1表示障碍。
构成迷宫的字符型数组,以空白字符表示通路,以字符‘#’表示障碍,并在迷宫四周加上一圈障碍。
MazePath(&
M)
迷宫M已被赋值。
若迷宫M中存在一条通路,则按如下规定改变迷宫M的状态:
以字符“*”表示路径上的位置,字符“@”表示“死胡同”;
否则迷宫的状态不变。
PrintMaze(M)
迷宫M已存在。
以字符形式输出迷宫。
}ADTmaze;
3.本程序包含三个模块
1)主程序模块
voidmain()
{初始化
do{
接受命令;
处理命令;
}while(命令!
=“退出”);
}
2)栈模块----实现栈抽象数据类型
3)迷宫模块----实现迷宫抽象数据类型
各模块之间的调用关系如下:
主程序模块
迷宫模块
栈模块
4.求解迷宫中一条通路的伪码算法:
设定当前位置的初值为入口位置;
若当前位置可通,
则{将当前位置插入栈顶;
//纳入路径
若该位置是出口位置,则结束;
//求得路径存放在栈中
否则切换当前位置的东邻方块为新的当前位置;
否则{
若栈不空且栈位置尚有其他方向未被探索,
则设定新的当前位置为沿顺时针方向旋转找到的栈顶位置的下一相邻块;
若栈不空但栈顶位置的四周均不可通,
则{删去栈顶位置;
//后退一步,从路径中删去该通道块,
若栈不空,则重新测试新的栈顶位置,
直到找到一个可通的相邻块或出栈至栈空;
}while(栈不空);
{栈空说明没有路径存在}
详细设计示例如下:
1.坐标位置类型
typedefstruct{
intr,c;
//迷宫中行、列的范围
}PosType;
2.迷宫类型
intm,n;
chararr[RANGE][RANGE];
//各位置取值‘’,‘#’,‘@’或‘*’
}MazeType;
voidInitMaze(MazeType&
maze,inta[][],introw,intcol)
//按照用户输入的row行和col列的二维数组(元素值为0或1)
//设置迷宫的初值,包括加上边缘一圈的值
boolMazePath(MazeType&
maze,PosTypestart,PosTypeend)
//求解迷宫maze中,从入口start到出口end的一条路径
//若存在,则返回TRUE;
否则返回FALSE
voidPrintMaze(MazeTypemaze)
//将迷宫以字符型方阵的形式输出到标准输出文件上
3.栈类型
intstep;
//当前位置在路径上的“序号”
PosTypeseat;
//当前的坐标位置
directiveTypedi;
//往下一坐标位置的方向
}ElemType;
//栈的元素类型
typedefstructNodeType{
ElemTypedata;
NodeType*next;
}NodeType,*LinkType;
//结点类型,指针类型
LinkTypetop;
intsize;
}Stack;
//栈类型
栈的基本操作设置如下:
voidInitStack(Stack&
//初始化,设S为空栈(S.top=NULL)
voidDestroyStack(stack&
//销毁栈S,并释放所占空间
voidClearStack(Stack&
//将S清为空栈
intstackLength(StackS)
//返回栈S的长度S.size
StatusStackEmpty(StackS)
//若S为空栈(S.top==NULL),则返回TRUE;
StatusGetTop(Stacks,ElemTypee)
//若栈S不空,则以e带回栈顶元素并返回TRUE,否则返回FALSE;
StatusPush(Stack&
S,ElemTypee)
//若分配空间成功,则在S的栈顶插入新的栈顶元素e,并返回TRUE,
//否则栈不变,并返回FALSE
StatusPop(Stack&
S,ElemType&
//若栈不空,则删除S的栈顶元素并以e带回其值,且返回TRUE
//否则返回FALSE
voidStackTraverse(Stacks,Status(*visit)(ElemTypee))
//从栈底到栈顶依次对S中的每个结点调用函数visit
其中部分操作的算法:
S,ElemTypee)
{//若分配空间成功,则在S的栈顶插入新的栈顶元素e,并返回TRUE;
//否则栈不变,并返回FALSE
if(MakeNode(p,e)){
p->
next=s.top;
s.top=p;
s.size++;
returnTRUE;
elsereturnFALSE;
{//若栈不空,则删除S的栈顶元素并以e带回其值,且返回TRUE,
//否则返回FALSE,且e无意义
if(StackEmpty(S))returnFALSE;
else{
p=S.top;
S.top=S.top->
next;
e=p->
date;
S.size--;
}
4.求迷宫路径的伪码算法:
StatusMazePath(MazeTypemaze,PosTypestart,PosTypeend)
{
//若迷宫中存在从入口start到出口end的通道,则求得一条存入在栈中
//(从栈底到栈顶为从入口到出口的路径),并返回TRUE;
InitStack(S);
curpos=start;
//设定“当前位置”为“入口位置”
curstep=1;
found=FALSE;
//探索第一步
if(Pass(maze,curpos)){
//当前位置可以通过,即是未曾走到过的通道块留下足迹
FootPrint(maze,curpos);
e=(curstep,curpos,1);
Push(S,e);
//加入路径
if(Same(curpos,end))found=TRUE;
//到达终点(出口)
curpos=NextPos(curpos,1);
//下一位置是当前位置的东邻
curstep++;
//探索下一步
}//else
}//if
else//当前位置不能通过
if(!
StackEmpty(S)){
Pop(S,e);
while(e.di==4&
&
!
MarkPrint(maze,e,seat);
curstep--;
//留下不能通过的标记,并退回一步
}//while
if(e.di<
4){
e.di++;
Push(S.e);
//换下一个方向探索
curpos=NextPos(e.seat,e.di);
//设定当前位置是该新方向上的相邻块
}//if
}while(!
StackEmpty(S)&
found);
returnfound;
}//MazePath
5.主函数和其他函数的伪码算法
voidmain()
{//主程序
Initialization();
//初始化
do{
ReadCommand(cmd);
//读入一个操作命令符
Interpret(cmd);
//解释执行操作命令符
}while(cmd!
=‘q’&
cmd!
=‘Q’);
}//main
voidInitialization()
{//系统初始化
clrscr();
//清屏
在屏幕上方显示操作命令清单:
CreatMaze—cMazePath—mPrintMaze—pQuit—q;
在屏幕下方显示操作命令提示框:
}//Initialization
voidReadCommand(char&
cmd)
{//读入操作命令符
显示键入操作命令符的提示信息;
cmd=getche()
}while(cmd[‘c’,‘C’,‘m’,‘M’,‘p’,‘P’,‘q’,‘Q’]);
}//ReadCommand
voidInterpret(charcmd)
{//解释执行操作命令
switch(cmd){
case‘c’,’C’:
提示用户输入“迷宫数据的文件名filename”;
从文件读入数据分别存储在rnum,cnum和二维数组a2中;
InitMaze(ma,a2,rnum,cnum);
//创建迷宫
输出迷宫建立完毕的信息
break;
case‘m’,‘M’:
提示用户输入迷宫的入口from和出口term的坐标位置;
if(MazePath(ma,from,term))//存在路径
提示用户察看迷宫;
else输出该迷宫没有从给定的入口到出口的路径的信息;
break;
case‘p’,‘P’:
PrintMaze(ma):
//将标记路径信息的迷宫输出到终端
}//switch
}//InterPret
6.函数的调用关系图反映了演示程序的层次结构:
主程序
InitializationReadCommandInterPret
InitMazeMazePathPrintMaze
InitStackPushPopStackEmptyStackTraverse
FootPrintMarkPrintPassNextPosSame
源程序文件名清单:
base.H//公用的常量和类型
stkpas.H//栈类型
maze.H//迷宫类型
testmaze.C//主程序
【实例测试及运行结果】
迷宫的测试数据如下:
左上角(1,1)为入口,右下角(9,8)为出口。
1
当入口位置为(1,1),出口位置为(9,8)时,输出数据应为:
*
#
@
测试结果示例:
三组测试数据和输出结果分别如下:
1.输入文件名为:
m1.dat,其中迷宫数据为:
32
00
入口位置:
11
出口位置:
求解路径后输出的迷宫:
2.输入文件名:
m2.dat,其中迷宫数据为:
34
0000
0011
0000
3.输入文件名:
m3.dat,其中迷宫数据同题目中的测试数据。
98
求解路径后输出的迷宫正确,并和需求分析中所列相同。
4.输入文件名:
m4.dat,其中迷宫数据为:
49
000000100
010001000
001110011
001110100
输出信息为:
此迷宫从入口到出口没有路径。
【实现提示】
计算机解迷宫通常用的是“穷举求解”方法,即从入口出发,顺着某一个方向进行探索,若能走通,则继续往前走;
否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。
假如所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。
可以二维数组存储迷宫数据,通常设定入口点的下标为(1,1),出口点的下标为(m,n)。
为处理方便起见,可在迷宫的四周加一圈障碍。
对于迷宫中任一位置,均可约定有东、南、西、北四个方向可通。
用户手册:
(1)本程序的运行环境为DOS操作系统,执行文件为:
TestMaze.exe
(2)进入演示程序后,即显示文本方式的用户界面:
(3)进入“产生迷宫(CreatMaze)”的命令后,即提示键入迷宫数据的文件名,结束符为“回车符”,该命令执行之后输出“迷宫已建成”。
(4)进入“求迷宫路径(MazePath)”的命令后,即提示键入入口位置(行号和列号,中间用空格分开,结束符为“回车符”)和出口位置(行号和列号,中间用空格分开,结束符为“回车符”),该命令执行之后输出相应信息。
若迷宫中存在路径,则执行此命令后,迷宫状态已改变,若要重复执行此命令,无论是否改变出口和入口的位置,均需重新输入迷宫数据。
(5)输入“显示迷宫”的命令后,随即输出当前的迷宫,即迷宫的初始状态或求出路径之后的状态。
心得体会:
1.本次作业比较简单,只有一个核心算法,即求迷宫的路径,所以总的调试比较顺利,只在调试MazePath算法时,遇到两个问题:
其一是,起初输出的迷宫中没有加上‘@’的记号,后发现是因为在MarkPrint函数中的迷宫参数丢失“变参”的原因;
其二是,由于回退时没有将curpos随之减一,致使栈中路径上的序号有错。
2.栈的元素中的step域没有太多用处,可以省略。
3.StackTraverse在调试过程中很有用,它可以插入在MazePath算法中多处,以察看解迷宫过程中走的路径是否正确,但对最后的执行版本没有用。
4.本题中三个主要算法:
InitMaze,MazePath和PrintMaze的时间复杂度均为0(m*n),本题的空间复杂度亦为0(m*n)(栈所占最大空间)
5.经验体会:
借助DEBUG调试器和数据观察窗口,可以加快找到程序中疵点。
【选作内容】
(1)编写递归形式的算法,求得迷宫中所有可能的通路;
(2)以方阵形式输出迷宫及其通路。
三.设计题目
1.文本文件单词的检索与计数
1.1【问题描述】
串是非数值处理中的主要对象,如在信息检索、文本编辑、符号处理等许多领域,得到越来越广