迷宫问题:给定一个迷宫的入口,找出迷宫的一条通路。
【解决办法】
1.迷宫放在一个文件里,我们将迷宫读取出来存储在一个二维数组中, 用'0'来表示通路,'1'表示不通。
2.每次探测当前位置的上下左右,如果是通路,压栈,继续探测;如果不是通路,从栈中弹出,回溯到上一个走过位置。
3.利用二维数组下标的界限来判断是否找到出口。
【代码】
1.Maze.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include "Stack.h"
using namespace std;
struct Pos
{
Pos(int row = 0, int col = 0)
:_row(row)
, _col(col)
{}
int _row;
int _col;
};
void InitMazeMap(char* map, int row, int col);
void PrintMazeMap(char* map, int row, int col);
bool GetPath(char* map, int row, int col, Pos enter,Stack<Pos>& path);
bool IsExport(const Pos& pos, int row, int col);
bool IsAccess(const Pos& pos, char* map, int row, int col);
void GetSize(int* prow, int* pcol);
2.Maze.cpp
<pre class="cpp" name="code">#include "Maze.h"
#include <cassert>
void InitMazeMap(char* map, int row, int col)
{
FILE* f1 = fopen("MazeMap.txt", "r");
assert(f1);
//跳过第一行
int ch = fgetc(f1);
while (ch != '\n')
{
ch = fgetc(f1);
}
//开始读取迷宫地图
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col;)
{
ch = fgetc(f1);
if (ch == '0' || ch == '1')
{
map[i*col + j] = ch;
++j;
}
}
}
fclose(f1);
}
void PrintMazeMap(char* map, int row, int col)
{
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col; ++j)
{
cout << map[i*col + j] << " ";
}
cout << endl;
}
cout << endl;
}
//找通路
bool GetPath(char* map, int row, int col, Pos enter, Stack<Pos>& path)
{
map[enter._row*col + enter._col] = '2';
path.Push(enter);
while (!path.Empty())
{
Pos cur = path.Top();
if (cur._col!= enter._col && cur._row!=enter._row && IsExport(cur,row,col))
{
return true;
}
//上
Pos next = cur;
next._row -= 1;
if (IsAccess(next,map,row,col))
{
map[next._row*col + next._col] = '2';
path.Push(next);
continue;
}
//右
next = cur;
next._col += 1;
if (IsAccess(next, map, row, col))
{
map[next._row*col + next._col] = '2';
path.Push(next);
continue;
}
//下
next = cur;
next._row += 1;
if (IsAccess(next, map, row, col))
{
map[next._row*col + next._col] = '2';
path.Push(next);
continue;
}
//左
next = cur;
next._col -= 1;
if (IsAccess(next, map, row, col))
{
map[next._row*col + next._col] = '2';
path.Push(next);
continue;
}
map[cur._row*col + cur._col] = '3';
path.Pop();
}
return false;
}
//判断pos位置是否通
bool IsAccess(const Pos& pos, char* map, int row, int col)
{
if (pos._row >= 0 && pos._row < row
&&pos._col >= 0 && pos._col < col
&&map[pos._row*col + pos._col] == '0')
{
return true;
}
else
{
return false;
}
}
//判断pos位置是否为出口
bool IsExport(const Pos& pos, int row ,int col)
{
if (pos._col == 0 || pos._row == 0 || pos._col == (col - 1) || pos._row == (row - 1))
{
return true;
}
else
{
return false;
}
}
//从文件中获取迷宫的大小
void GetSize(int* prow, int* pcol)
{
FILE* f = fopen("MazeMap.txt", "r");
assert(f);
int ch = fgetc(f);
while (ch != '\n' && (ch <= '0' || ch >= '9'))//跳过非数字字符
{
ch = fgetc(f);
}
while (ch >= '0'&&ch <= '9') //row
{
*prow = *prow * 10 + (ch - '0');
ch = fgetc(f);
}
while (ch != '\n'&& (ch<='0' || ch>='9'))
{
ch = fgetc(f);
}
while (ch >= '0' && ch <= '9')//col
{
*pcol = *pcol * 10 + (ch - '0');
ch = fgetc(f);
}
fclose(f);
}
3.Stack.h(这里为了复习,我将栈实现了一遍。这里可以直接用库里面的栈,就不需要自己实现了)
#pragma once
#include <cassert>
#include <iostream>
using namespace std;
template <class T>
class Stack
{
public:
Stack()
:_data(NULL)
, _size(0)
, _capacity(0)
{}
~Stack()
{
if (_data != NULL)
{
delete _data;
_data = NULL;
_size = 0;
_capacity = 0;
}
}
void Push(const T& data)
{
CheckCapacity();
_data[_size++] = data;
}
void Pop()
{
assert(_size > 0);
_size--;
}
T& Top() const
{
assert(_size > 0);
return _data[_size - 1];
}
bool Empty() const
{
return _size == 0;
}
size_t Size() const
{
return _size;
}
protected:
void CheckCapacity()
{
if (_size == _capacity)
{
size_t newCapacity = _capacity * 2 + 3;
T* tmp = new T[newCapacity];
for (size_t i = 0; i < _size; ++i)
{
tmp[i] = _data[i];
}
delete _data;
_data = tmp;
_capacity = newCapacity;
}
}
protected:
T* _data;
size_t _size;
size_t _capacity;
};
4.Test.cpp
#include "Stack.h"
#include "Maze.h"
void TestStack()
{
Stack<int> s1;
s1.Push(1);
s1.Push(2);
s1.Push(3);
s1.Push(4);
while (!s1.Empty())
{
cout << s1.Top() << endl;
s1.Pop();
}
}
void TestMaze()
{
int row = 0;
int col = 0;
GetSize( &row, &col);
char* Map = (char*)malloc((row*col)*sizeof(char));
Pos mEnter(2, 0);
Stack<Pos> path;
InitMazeMap( Map, row, col);
PrintMazeMap(Map, row, col);
if(GetPath(Map, row, col, mEnter, path))
{
PrintMazeMap(Map, row, col);
}
else
{
cout << "没有通路"<<endl;
}
free(Map);
}
int main()
{
TestMaze();
system("pause");
return 0;
}