迷宫最短路径c/c++

新建一个地图文件,格式如下

maze.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include"maze.h"
#include<fstream>
#include<string>
#include<assert.h>

//新建一个txt文件,里面存一串1,0的数字作为地图。
// 格式如下(必须按照此格式)
//h:14
//l:15
//map:
//01110100001001
//00000001010000
//00101010101001
//11000101000000
//00000010101111
//01111010000000
//00000000010011
//01111100111000
//10000000000001
//01110010001101
//10000011110100
//01011100000000
//11100000010101
//00000110100000
//00111000011010

//读取文件内的内容作为地图
void getmap(maze *lty)
{
	FILE* f = fopen("C:\\Users\\luotianyi\\Desktop\\map.txt","rb+");
	if (f)
	{
		cout << "打开文件成功" << endl;
	}
	else
	{
		cout << "打开文件失败" << endl;
		perror("open file fail");
		return;
	}
	int hang = 0;
	int lie = 0;
	while (fgetc(f) != 'h')	//读取到 h
	{
	}
	fseek(f, 1, SEEK_CUR);	//向后偏移1(跳过:)
	int k = 0;		//用来接收字符串转int的值
	string han;	//读取的行存在这里面
	while ((k = fgetc(f)) >= 48 && k <= 57)	//往后读取到的数字字符都追加进han里
	{
		han += k;
	}
	hang=std::stoi(han);	//string转int
	lty->h = hang;
	while (fgetc(f) != 'l')//读取到 l
	{
	}
	fseek(f, 1, SEEK_CUR);	//向后偏移1(跳过:)
	k = 0;
	string li;	//读取到的列存到这里面
	while ((k = fgetc(f)) >= 48 && k <= 57)	//往后读取到的数字字符追加进li里
	{
		li += k;
	}
	lie = std::stoi(li);	//string转int之后存进lie里
	lty->l = lie;
	int** t = new int* [hang];
	for (int k = 0; k < hang; k++)		//创建二维数组当做地图
	{
		t[k] = new int[lie];
	}
	while (fgetc(f) != 'p')//读取到 p
	{
	}
	k = 0;
	while (k< 48 || k > 57)	//map:找完找下一排.
	{
		k = fgetc(f);
	}
	fseek(f, -1, SEEK_CUR);	//向前偏移1 ,指针走到数字字符前面
	for (int x = 0; x < hang; x++)
	{
		printf("第%d排\n", x);	//查看地图每一排
		for (int y = 0; y < lie; y++)
		{
			auto k = fgetc(f)-48;	
			t[x][y] = k;
			printf("%d ", k);	//查看每次获取的地图块儿
		}
		cout << endl;
		k = 0;
		while ((k < 48 || k > 57)&&k!=EOF)	//map:找完找下一排.EOF文件结束标志
		{
			k = fgetc(f);
		}
		fseek(f, -1, SEEK_CUR);	//向前偏移1 ,指针走到数字字符前面
	}
	lty->lty = t;
	fclose(f);
	f = nullptr;
}


void test()
{
	int a = 15;		//地图的长宽
	int b = 14;
	stack yyy;		//栈
	stinit(&yyy);
	stack minyyy;	//最小路径栈
	stinit(&minyyy);
	maze lty(0,0);
	getmap(&lty);	//获取地图
	lty.look();			//查看地图
	cout << endl << endl;	
	pos cur(0, 0);		//当前位置类
	getpath(lty.lty, lty.h, lty.l, cur, &yyy, &minyyy);		//走迷宫,获取路径
	if (minyyy.top == 0)    //如果最小路径栈里没有数据
	{
		cout << "没有通路" << endl;
	}
	else
	{
		cout << "最少多少步可以走到:" << minyyy.top << endl << endl;;

		for (int k = 0; k <= minyyy.top - 1; k++)
		{
			cout << '[' << minyyy.lty[k].l + 1 << "," << minyyy.lty[k].h + 1 << ']' << " -> ";
		}
	}
	delete[] yyy.lty;
	yyy.lty = nullptr;
	yyy.top = yyy.capacity = 0;
	delete[] minyyy.lty;
	minyyy.lty = nullptr;
	minyyy.top = minyyy.capacity = 0;
}

int main()
{
	test();
	return 0;
}


maze.h

#pragma once
#include<iostream>
using namespace std;
#include<assert.h>


class maze
{
public:
	maze(int a,int b);
	~maze();
	void look();	//查看地图

	int h;		//行
	int l;		//列
	int** lty;	//地图数组
};

maze::maze(int a=0,int b=0)	//构造地图
	:h(a),l(b),lty(nullptr)
{
}

maze::~maze()	//析构地图
{
	for (int k = 0; k < h; k++)
	{
		delete[]lty[k];
		lty[k] = nullptr;
	}
	delete[] lty;
	lty = nullptr;
	h = l = 0;
}

void maze::look()	//看看地图
{
	cout << endl;
	for (int m = 0; m < h; m++)
	{
		for (int n = 0; n < l; n++)
		{
			printf("%-2d ", lty[m][n]);
		}
		cout << endl;
	}
	cout << endl;
}

class pos	//位置类(当前位置/下一个位置)
{
public:
	pos(int a=0, int b=0)
		:h(a), l(b)
	{
	}
	int h;	//行
	int l;	//列
};


typedef struct stack	//栈,用来储存走过的路径
{
	pos* lty;	//一个储存位置的数组指针,每个元素是pos(一个坐标)
	int top;	//栈顶的下一个位置
	int capacity;	//栈空间大小
}stack;
void stinit(stack*a,int b=20)	//初始化栈,默认初始化20个空间
{
	 a->lty = new pos[b];
	 a->capacity = b;
	 a->top = 0;
}
void stacket(stack *a)	//栈扩容
{
	if (a->capacity == a->top)
	{
		pos* temp= (pos*)realloc(a->lty, a->capacity * 1.5 * sizeof(pos));
		if (temp == nullptr)
		{
			assert(temp);
		}
		a->lty = temp;
		a->capacity = 1.5 * a->capacity;
	}
}

void push(stack *a,pos b)	//入栈
{
	stacket(a);
	a->lty[a->top] = b;
	a->top++;
}
void pop(stack* a)	//出栈
{
	a->top--;
}


bool ispass(int** lty, int n, int m, pos next)	//下一个坐标next能否走通
{
	if (next.h >= 0 && next.h <= n - 1
		&& next.h >= 0 && next.l <= m - 1
		&& lty[next.h][next.l] == 0
		)
	{
		return true;
	}
	else
	{
		return false;
	}
}



void getpath(int** lty, int n, int m, pos cur, stack* a,stack*min)		//走迷宫,获取路径
{
	push(a, cur);	//起点坐标入栈,每次递归进来,相当于以新的当前坐标为起点
	if (cur.h == n - 1 && cur.l == m - 1)	//如果到了终点
	{
		if (min->top == 0||min->top>a->top)	//如果最小路径栈==0或者最小步数大于当前步数
		{
			min->top = 0;	//将最小路径栈置0
			for (int k = 0; k < a->top; k++)	//把当前路径栈拷贝到最小路径栈上
			{
				pos temp;
				temp.h = a->lty[k].h;
				temp.l = a->lty[k].l;
				push(min, temp);
			}
		}
	}

	pos next(0, 0);
	lty[cur.h][cur.l] = 2;
	//上
	next = cur;
	next.h -= 1;
	if (ispass(lty, n, m, next))
	{
		getpath(lty, n, m, next, a, min);
		//cout << next.h << " " << next.l << endl;
	}

	//下
	next = cur;
	next.h += 1;
	if (ispass(lty, n, m, next))
	{
		getpath(lty, n, m, next, a, min);
		//cout << next.h << " " << next.l << endl;
	}

	//左
	next = cur;
	next.l -= 1;
	if (ispass(lty, n, m, next))
	{
		getpath(lty, n, m, next, a, min);
		//cout << next.h << " " << next.l << endl;
	}

	//右
	next = cur;
	next.l += 1;
	if (ispass(lty, n, m, next))
	{
		getpath(lty, n, m, next, a, min);
		//cout << next.h << " " << next.l << endl;

	}
	lty[cur.h][cur.l] = 0;   //走过的路径置0
	pop(a);	//递归结束出栈
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值