寻找迷宫出口<一>
<coad = C++>
小程序目的: 判断在一个10*10的矩阵中是否可以找到迷宫的出口;
PS:程序功能比较单一,还有许多可以改进的地方,比如,可以寻找出口的最优路径,可是我现在没有想出来,
所以,在 寻找迷宫出口<二> 我会对迷宫问题做出进一步的完善!
-----------------------------------------------------------------------------
程序所用到的迷宫模板,和需要动态开辟的数组大小; 包含在文件“ test.txt”中
10 10
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
0 0 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 0 0 0 0 0 1 1
1 1 0 1 1 1 1 0 1 1
1 1 0 1 1 1 1 0 1 1
1 1 0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
0 0 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 0 0 0 0 0 1 1
1 1 0 1 1 1 1 0 1 1
1 1 0 1 1 1 1 0 1 1
1 1 0 1 1 1 1 1 1 1
-----------------------------------------------------------------------------------------
程序运行结果:
----------------------------------------------
以下是程序的源代码,代码中表标有注释; coad = C++;
程序分为两部分,头文件Stack.h 包含头文件和对栈的实现;
maze.cpp包含对走迷宫的实现;
-------------------------------------------------------------------------------------------
Stack.h
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cassert>
using namespace std;
struct Pos//定位坐标,定位当前位置
{
int _row;
int _col;
Pos(int row = 0,int col = 0)
:_row(row)
,_col(col)
{}
};
template<typename T>
class Seqlist
{
public :
Seqlist()
:_pdata(NULL)
,_size(0)
,_capacity(3)
{
_pdata = new T[3];
}
~Seqlist()
{
cout<<"~Stack()"<<endl;
if(_pdata != NULL)
{
delete[] _pdata;
_size = 0;
_capacity = 0;
}
}
void push_back(const T& data)
{
check_capacity ();
_pdata[_size] = data;
_size++;
}
void pop_back()
{
assert(_pdata);
_size--;
}
protected:
void check_capacity()
{
if(_size == _capacity)
{
size_t NewCapacity = _capacity*2 + 3;
T* tmp = new T[NewCapacity];
for(int i = 0; i<_size; i++)
{
tmp[i] = _pdata[i];
}
delete[] _pdata;
_pdata = tmp;
_capacity = NewCapacity;
}
}
public:
size_t _size;// 方便访问,如果觉得不太好,可以封装一个公有的函数返回;
T* _pdata;
size_t _capacity;
};
template<class T,class Container=Seqlist<T> >
class Stack
{
public:
bool empty()
{
return _con._size==0;
}
size_t szie()
{
return _size;
}
T& top()
{
int size = _con._size - 1;
return _con._pdata[size];
}
void push(const T& data)
{
_con.push_back(data);
}
void pop()
{
_con.pop_back();
}
private:
Container _con;
};
maze.cpp
#pragma once
#include"Stack.h"
// 设为全局变量可以省去很多传参;
int*maze = NULL;
int rows = 0;
int cols = 0;
void init_maze()// 动态开辟二维数组,读取迷宫数组;
{
FILE* pf = fopen("test.txt","r");
assert(pf);
int tmp;
while((tmp = fgetc(pf))!=' ')
{
rows =rows*10 + tmp-'0';
}
while((tmp = fgetc(pf))!='\n')
{
cols = cols*10 +tmp-'0';
}
maze = (int*)malloc(rows*cols*sizeof(int));
//开辟rows*cols长度的数组,把它看作二维数组;
assert(maze);
for(int i = 0; i<rows; i++)
{
for(int j = 0; j<cols;)
{
tmp = fgetc(pf);
if(tmp!=EOF && tmp!=' ' && tmp!='\n')
{
maze[i*rows+j] = tmp-'0';
j++;
}
}
}
fclose(pf);
}
void printmaze()//打印迷宫
{
for(int i = 0; i<rows; i++)
{
for(int j = 0; j<cols;j++)
{
cout<<maze[i*rows+j]<<" ";
}
cout<<endl;
}
}
void make_push(Stack<Pos>& paths,Pos pos)//压栈,给走过的路径设置标志操作;
{
paths.push (pos);
maze[pos._row*cols + pos._col] = 2;
}
bool check_exit(const Pos& pos)
{
if(pos._row == 9 && pos._col == 2)
return true;
return false;
}
bool get_path(Stack<Pos>& paths,Pos pos)// 走迷宫,返回迷宫是否找到出口;
{
//应该封装一个函数专门负责压栈和对走过的坐标进行标记的任务;
//对四个方向的可行性进行判断;可行则压栈,不可行则Pop;应是一个循环;
//考虑是否遇到出口? 遇到出口则到达边缘值,没有出口则会回到出发点,即栈会为空;
make_push(paths,pos);//压栈,给走过的路径设置标志操作;
while(!paths.empty())
{
pos = paths.top();// 每次从栈顶读取一个元素;
int row_1 = pos._row - 1;
if(maze[row_1*cols + pos._col] == 0
&& row_1 >= 0 && row_1 < rows &&
pos._col >=0 && pos._col < cols)
{
pos._row = pos._row -1;
make_push(paths,pos);
continue ;
}
// 右
int col_1 = pos._col + 1;
if(maze[pos._row * cols + col_1] == 0
&& pos._row >= 0 && pos._row < rows &&
col_1 >=0 && col_1 < cols)
{
pos._col+=1;
make_push(paths,pos);
continue ;
}
// 左
col_1 = pos._col - 1;
if(maze[pos._row * cols + col_1] == 0
&& pos._row >= 0 && pos._row < rows &&
col_1 >=0 && col_1 < cols)
{
pos._col -= 1;
make_push(paths,pos);
continue ;
}
//下
row_1 = pos._row + 1;
if(maze[row_1*cols + pos._col] == 0
&& row_1 >= 0 && row_1 < rows &&
pos._col >=0 && pos._col < cols)
{
pos._row+=1;
make_push(paths,pos);
continue ;
}
if(check_exit(pos))//检查如果到达出口则返回ture;
return true;
paths.pop ();//四个方向都不通,则删除一个栈顶元素;
}
return false;//栈为空代表没有出口,返回false;
}
void free_memery()//千万别因为程序运行出来了而忘了释放内存;
{
free(maze);
maze = NULL;
}
int main()
{
init_maze();//从文件中将迷宫读取到二维数组中;
printmaze();//打印迷宫;
Stack<Pos> paths;
//用栈的目的在于保存以前走过的路径,万一走到死胡同,还有回旋的余地;
cout<<"此迷宫是否有通路:\n1:有\n0:没有\n结果:"<<get_path(paths,Pos(2,0))<<endl;
printmaze();
//再打印一次迷宫;
free_memery();
//paths对象在程序结束后会自己调用析构函数;
system("pause");
return 0;
}
代码比较粗糙,如有问题,欢迎指出!