寻找迷宫出口<一>

寻找迷宫出口<一>

<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

-----------------------------------------------------------------------------------------

程序运行结果:



----------------------------------------------

以下是程序的源代码,代码中表标有注释; 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;
}

代码比较粗糙,如有问题,欢迎指出!

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值