实验难度: A □ B □ C □序号学号姓名成绩指导教师(签名)学期:2017秋季学期任课教师:实验题目:组员及组长:承担工作:联系电话:电子邮件:完成提交时间:年月日一、【实验构思(Conceive)】(10%)(本部分应包括:描述实验实现的基本思路,包括所用到的离散数学、工程数学、程序设计等相关知识,对问题进行概要性地分析)首先输入迷宫数据,在计算机的屏幕上显示一个8行8列的矩阵表示迷宫。
矩阵中的每个数据或为通路(以0表示),或为墙(以1表示),所求路径必须是简单路径,即在求得的路径上不能重复出现同一道块。
假设以栈S记录“当前路径”,则栈顶中存放的是“当前路径上最后一个通道块”。
由此,“纳入路径”的操作为“当前位置入栈”;从当前路径删除前一通道块的操作为“出栈”。
若找到出口,则从栈中弹出数据,在屏幕上显示从入口到出口的路径坐标。
二、【实验设计(Design)】(20%)(本部分应包括:抽象数据类型的定义和基本操作说明,程序包含的模块以及各模块间的调用关系,关键算法伪码描述及程序流程图等,如有界面则需包括界面设计,功能说明等)1、定义坐标(X,Y):struct Coor{int row;int column;int direction;};2、定义方向:struct Move{int row;int column;};3、定义/链表结点:struct LinkNode{Coor data;LinkNode *next;};4、定义栈:class stack{private:LinkNode *top;public:stack();~stack();void Push(Coor data);Coor Pop();Coor GetPop();void Clear();bool IsEmpty();};5.流程图:三、【实现(Implement)】(30%)(本部分应包括:抽象数据类型各操作的具体实现代码、关键操作的具体算法实现、函数实现,主程序实现等,并给出关键算法的时间复杂度分析。
如有界面则需包括界面的关键实现方法等。
)1.定义迷宫定义移动的4个方向:Move move[4]={{0,1},{1,0},{0,-1},{-1,0}};2.几个函数功能的描述:stack(); //构造函数,置空栈~stack(); //析构函数void Push(Coor data); //把元素data压入栈中Coor Pop(); //使栈顶元素出栈Coor GetPop(); //取出栈顶元素void Clear(); //把栈清空bool IsEmpty(); //判断栈是否为空bool Mazepath(int **maze,int m,int n);//寻找迷宫maze中从(0,0)到(m,n)的路径//到则返回true,否则返回falsevoid PrintPath(stack p); //输出迷宫的路径void PrintPath2(int m,int n,stack p,int **maze); //输出路径void Restore(int **maze,int m,int n); //恢复迷宫3.主函数实现:int main(){system("color f5");int m=0,n=0;int **maze; //定义二维指针存取迷宫cout << "**************欢迎使用迷宫游戏模拟程序*************" << endl;cout << "* 软件工程*" << endl;cout << "* 孙越*" << endl;cout << "* 20161120232 *" << endl;cout << "***************************************************" << endl;maze=GetMaze(m,n); //调用GetMaze函数,得到迷宫if(Mazepath(maze,m,n)) //调用Mazepath函数获取路径cout<<"迷宫路径探索成功!\n";elsecout<<"路径不存在!\n";return 0;}4.复杂度分析:空间复杂度:O(1);时间复杂度:随机生成迷宫:O(n*n);探寻出口:O(n*n);输出迷宫:O(n*n);判断当前位置可通:O(1)。
四、【测试结果(Testing)】(10%)(本部分应包括:对实验的测试结果,应具体列出每次测试所输入的数据以及输出的数据,并对测试结果进行分析,可附截图)1. 选择以坐标形式输出迷宫:输出如下图所示:2.选择以方阵形式输出迷宫:输出如下图所示(其中8代表路径,1代表墙)3.迷宫不存在,路径探索失败:五、【实验总结】(10%)(本部分应包括:自己在实验中完成的任务,及存在的问题,所完成实验过程中的具体经验总结、心得)通过该题目的设计过程,我加深了对栈的逻辑结构,存储结构及入栈出栈过程的理解,对栈的基本运算的实现有所掌握,对课本中所学的各种数据结构进一步理解和掌握,学会了如何把学到的知识用于解决实际问题,锻炼了自己动手的能力。
但是程序依旧还存在一些问题,比如开始的时候,调试过程中自己定义不可通取值从ch>='0'&&ch<='9'都可以执行,但是在执行过程中显示迷宫时有“吃墙”现象,有一部分“墙”出现缺失。
经过反复调试程序,最后发现在定义if(maze[p][q]==1)cout<<"□";出错,后来改为if(maze[p][q]>=1)cout<<"□";后,吃图现象再没有发生。
但是处理了这个问题后还是会在显示迷宫模块的时候有一些迷宫方格,但经过多次调试后还是没能解决。
六、思考题或【项目运作描述(Operate)】(10%)(注:选择C难度的才需要填写“项目运作描述”,其他难度的只需完成思考题)(项目运作描述应包括:项目的成本效益分析,应用效果等的分析。
)接到实验项目后,其实第一个想法是看实验指导书,看了实验指导书之后知道了要设计该程序大概需要什么模块函数,然后根据这些模块一个个做出分析。
跟据实现提示,计算机解迷宫通常用的是“穷举求解”方法,即从人口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。
假如所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。
用二维数组指针存储迷宫数据,通常设定人口点的下标为(1,1),出口点的下标为(n,n)。
为处理方便起见,可在迷宫的四周加一圈障碍。
对于迷宫中任一位置,均可约定有东、南、西、北四个方向可通。
主要操作如下:1、生成迷宫:根据提示输入数据,然后生成一个8行8列的迷宫。
2、探索迷宫路径:由输入的入口位置开始,对相邻的(上,下,左,右)四个方向的方块进行探索,若可通则“纳入路径”,否则顺着“来向”退到“前一通道块”,朝着“来向”之外的其它方向继续探索。
3、保存迷宫路径:若探索到出口则把探索到的路径压入另一个栈中,并最后弹出路径坐标,输出在屏幕上。
将一个个函数完善后,最重要的就处理函数接口,怎样使各个子模块实施其的详细功能是一个很重要的问题,只有解决了这个问题才能充分调用这些函数,让主程序能够有效调用这些函数。
其中最主要的函数就是获取迷宫的二维指针函数和寻找迷宫路径函数,需要弄清楚二维数组指针的操作。
最后就是在main()函数中调用这些函数,画了一个函数调用的流程图,根据流程图调用函数,即可实现迷宫问题的操作。
七、【代码】(10%)(本部分应包括:完整的代码及充分的注释。
注意纸质的实验报告无需包括此部分。
格式统一为,字体: Georgia , 行距: 固定行距12,字号: 小五)#include<iostream>#include<fstream>#include<stdlib.h>#define true 1#define false 0using namespace std;struct Coor //定义描当前位置的结构类型{int row;int column;int direction;};struct Move //定义下一个位置的方向{int row;int column;};struct LinkNode //链表结点{Coor data;LinkNode *next;};class stack //定义栈{private:LinkNode *top;public:stack(); //构造函数,置空栈~stack(); //析构函数void Push(Coor data); //把元素data压入栈中Coor Pop(); //使栈顶元素出栈Coor GetPop(); //取出栈顶元素void Clear(); //把栈清空int IsEmpty(); //判断栈是否为空};stack::stack() //构造函数,置空栈{top=NULL;}stack::~stack() //析构函数{}void stack::Push(Coor x)//把元素data压入栈中{LinkNode *TempNode;TempNode=new LinkNode;TempNode->data=x;TempNode->next=top;top=TempNode;}Coor stack::Pop() //使栈顶元素出栈{Coor Temp;LinkNode *TempNode;TempNode=top;top=top->next;Temp=TempNode->data;delete TempNode;return Temp;}Coor stack::GetPop() //取出栈顶元素{return top->data;}void stack::Clear() //清空栈{top=NULL;}int stack::IsEmpty() //判断是否空栈{if(top==NULL)return true;elsereturn false;}Move move[4]={{0,1},{1,0},{0,-1},{-1,0}}; //定义移动的4个方向int Mazepath(int **maze,int m,int n); //寻找迷宫maze中从(0,0)到(m,n)的路径,找到则返回true,否则返回falsevoid PrintPath(stack p); //输出迷宫的路径void PrintPath2(int m,int n,stack p,int **maze); //输出路径void Restore(int **maze,int m,int n); //恢复迷宫int** GetMaze(int &m,int &n); //获取迷宫//返回存取迷宫的二维指针int main(){system("color f5");int m=0,n=0;int **maze; //定义二维指针存取迷宫cout << "**************欢迎使用迷宫游戏模拟程序*************" << endl;cout << "* 软件工程*" << endl;cout << "* 孙越*" << endl;cout << "* 20161120232 *" << endl;cout << "***************************************************" << endl;maze=GetMaze(m,n); //调用GetMaze函数,得到迷宫if(Mazepath(maze,m,n)) //调用Mazepath函数获取路径cout<<"迷宫路径探索成功!\n";elsecout<<"路径不存在!\n";return 0;}int** GetMaze(int &m,int &n)//获取迷宫{ //返回存取迷宫的二维指针int **maze;int i=0,j=0;cout<<"请输入迷宫的行数和列数:(中间用空格键分开)";int a,b;cin>>a>>b;cout<<"请输入迷宫内容:(0表示通路,1表示不连通。