地图类:
#pragma once /* 动态地图:row和line都是可变 */ class Map { public: //row:行 line:列 date:数据的首地址 Map(int row = 10, int line = 10,int* data = nullptr); ~Map(); public: void setData(int* data);//设置数据 //x:行下标 y:列下标 int getXY(int x, int y) const//获得map某个位置的值 { return pMap[x][y]; } void setXY(int x, int y, int val)//设置map某个位置的值 { pMap[x][y] = val; } int getRow()const { return row; } int getLine() const { return line; } void draw(); private: int row; int line; int** pMap; }; #include "Map.h" #include <string.h> #include <iostream> #include <windows.h> using namespace std; Map::Map(int row, int line, int* data) :row(row), line(line) { //申请二维数组的内存 pMap = new int*[row];//保存每一行的首地址 for (int i = 0; i < row;i++) { pMap[i] = new int[line]; } setData(data); } void Map::setData(int* data) { //如果数据地址为nullptr,给数组的所有元素赋值为0 if (nullptr == data) { for (int i = 0; i < row; i++) { //1.目的地址 2.值 3.字节数 memset(pMap[i], 0, sizeof(int) * line);//将一段内存空间填入某个值 } } else { for (int i = 0; i < row; i++) { memcpy(pMap[i], data, sizeof(int) * line); data = data + line;//data偏移一行 } } } void Map::draw() { system("cls"); for (int i = 0; i < row;i++) { for (int j = 0; j < line;j++) { switch (pMap[i][j]) { case 0: cout << " "; break; case 1: cout << "墙"; break; case 2: cout << "人"; break; } } cout << endl; } Sleep(300); } Map::~Map() { }
搜索类:
#pragma once /* 搜索类,单例模式 */ #include<vector> #include <iostream> #include "Map.h" using namespace std; //点的结构体 struct Point { int x; int y; Point(int x, int y) :x(x), y(y) { } }; class Dfs { public: static Dfs* getInstance(); static void destory(); public: //最短路径 int pathMin; //查询状态 bool findStatus; //路径保存 vector<vector<Point> >path; //转向数组 int nextxy[4][2] ;//上下左右 //判断某个点是否可以走 bool checkPoint(Map* map, Map* flagMap,Point p); //查找路径 bool findPath(Map* map, Map* flagMap, int startx, int starty, int endx, int endy); //DFS void dfs(Map* map, Map* flagMap, Point p, Point endP, int step, vector<Point> vec); //显示 void display(Map* map); private: static Dfs* pDfs; Dfs(); Dfs(const Dfs& d); ~Dfs(); }; #include "Dfs.h" Dfs* Dfs::pDfs = nullptr; Dfs::Dfs() { pathMin = 1000000000; findStatus = false; nextxy[0][0] = -1; nextxy[0][1] = 0; nextxy[1][0] = 1; nextxy[1][1] = 0; nextxy[2][0] = 0; nextxy[2][1] = -1; nextxy[3][0] = 0; nextxy[3][1] = 1; } Dfs::~Dfs() { } Dfs* Dfs::getInstance(){ if (!pDfs) pDfs = new Dfs; return pDfs; } void Dfs::destory(){ if (pDfs) delete pDfs; pDfs = nullptr; } bool Dfs::checkPoint(Map* map, Map* flagMap, Point p) { //1.越界 if (p.x < 0 ||p. x >= map->getRow() || p.y < 0 || p.y >= map->getLine()) return false; //2.走过 if (1 == flagMap->getXY(p.x, p.y)) return false; //3.障碍物 if (1 == map->getXY(p.x, p.y)) return false; return true; } bool Dfs::findPath(Map* map, Map* flagMap, int startx, int starty, int endx, int endy) { //将起点放入path中 vector<Point>vec; vec.push_back(Point(startx, starty)); //将起点标记为走过 flagMap->setXY(startx, starty, 1); dfs(map, flagMap, Point(startx, starty) ,Point(endx, endy), 1, vec); return findStatus; } void Dfs::dfs(Map* map, Map* flagMap, Point p, Point endP, int step, vector<Point> vec) { //判断是否是终点 if (p.x == endP.x && p.y == endP.y) { //cout << "YES" << endl; findStatus = true; if (step < pathMin){ path.push_back(vec); pathMin = step; } } //剪枝 if (step > pathMin)return; //遍历周围四个点(上下左右) for (int i = 0; i < 4; i++) { int xx = p.x + nextxy[i][0];//x int yy = p.y + nextxy[i][1];//y if (checkPoint(map, flagMap, Point(xx,yy)))//判断这个点是否走得通 { //将该点放入path,标记为走过 vec.push_back(Point(xx, yy)); flagMap->setXY(xx, yy, 1); //递归这个点 dfs(map, flagMap, Point(xx, yy), Point(endP.x, endP.y), step + 1, vec);//在某一分支找出了出口 //将该点移出path,标记为没走过 vec.pop_back(); flagMap->setXY(xx, yy, 0); } } return; } void Dfs::display(Map* map){ int size = path.size(); for (Point point : path[size-1]) { //将point对应的点设置为2 map->setXY(point.x, point.y, 2); map->draw(); } }
测试类:
#include <iostream> #include "Map.h" #include "Dfs.h" #include <vector> using namespace std; int main() { //创建地图和标记地图 int data[10][10] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 1, 1, 1, 1, 1, 0, 0, 1 }, { 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }; Map map(10, 10, &data[0][0]);//寻路地图 Map flagMap(10, 10);//标记地图 map.draw(); int startx, starty;//起始点 cout << "请输入起始点" << endl; cin >> startx >> starty; int endx, endy;//结束点 cout << "请输入结束点" << endl; cin >> endx >> endy; Dfs* find=Dfs::getInstance(); if (find->findPath(&map,&flagMap,startx,starty,endx,endy)) { find->display(&map); cout << "Success!" << endl; } else { cout << "Failed!" << endl; } return 0; }
面向对象封装dfs算法
最新推荐文章于 2023-09-12 10:51:35 发布