当前位置: 首页 > news >正文

栈实现走出迷宫(C++)

要求

  1. 将地图的数组保存在文件中,从文件中读取行列数
  2. 动态开辟空间保存地图
  3. 运行结束后再地图上标出具体的走法

说明

  1. 文件中第一行分别放置的是地图的行数和列数
  2. 其中1表示墙,即路不通,0表示路,即通路
  3. 程序运行结束后用2标记走过的路径
  4. 当走到“死胡同”时用3标记此路为死路
  5. 每到一个点,按照 左 上 右 下 的顺序去试探
  6. 从入口直到找到出口为止,打印出走过的坐标
  7. 没有找到出口返回false

地图截图

图片描述

代码示例

maze.h
#ifndef MAZE_H_
#define MAZE_H_
#include <iostream>
#include <string>
#include <stack>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

#define WALL 1
#define ROAD 0
#define SUCCESS 1;
#define ERROR 0;

class Seat{
public:
    Seat() // 无参构造函数 坐标默认 (0,0)
        :m_iX(0)
        ,m_iY(0)
    {}

    Seat(int x, int y) // 有参构造函数
        :m_iX(x)
        ,m_iY(y)
    {}

    bool operator==(const Seat &other){ // 重载坐标相等
        if(m_iX == other.m_iX && m_iY == other.m_iY)
            return true;
        return false;
    }

    int m_iX;
    int m_iY;
};


class Maze {
private:
    int** m_ppMap; // 指向地图的指针
    int m_iRow; // 存放地图的行数
    int m_iCol; // 存放地图的列数
public:
    Maze(const string& filePath); // 构造函数 初始化迷宫
    bool PassMaze(stack<Seat>& s, Seat& start, Seat& end); // 走出迷宫
    void PrintMap(); // 打印迷宫
    virtual ~Maze(); // 析构函数 释放内存
private:
    bool isPass(Seat& entry); // 判断是否为通路
};

#endif /* MAZE_H_ */
maze.cpp
#include "Maze.h"
#include <typeinfo>

Maze::Maze(const string& filePath) {
    fstream mapFile(filePath, ios::in);

    if(!mapFile.is_open()){
        cout << "读取文件失败" << endl;
    }

    string str_row_col; //第一行  获取行和列
    string str_temp;  // 临时字符串
    getline(mapFile, str_row_col);

    // 获取行列的个数
    str_temp = str_row_col.substr(0, str_row_col.find_first_of(','));
    m_iRow = atoi(str_temp.c_str());
    str_temp = str_row_col.substr(str_row_col.find_first_of(',')+1); // 取得字符串中的列数
    m_iCol = atoi(str_temp.c_str());

    // 分配空间
    m_ppMap = new int*[m_iRow];
    for(int i = 0; i < m_iRow; ++i){
        m_ppMap[i] = new int[m_iCol];
    }

    // 填充地图
    int index_row = 0; // 放置地图 二维数组的行索引
    int index_col = 0; // 放置地图 二维数组的列索引
    while(! mapFile.eof()){
        getline(mapFile, str_temp);
        char* a_line = (char*)str_temp.c_str();

        while(*a_line != '\0'){
            if(*a_line == '0' || *a_line == '1'){
                m_ppMap[index_row][index_col++] = *a_line - '0';
            }
            a_line++;
        }
        ++index_row;
        index_col = 0;
    }

    mapFile.close();


}

bool Maze::PassMaze(stack<Seat>& s, Seat& start, Seat& end) {

    if( !isPass(start) ){
        return false;
    }

    s.push(start);//压栈当前位置

    while(!s.empty()){// 栈不为空继续

        // 取得栈顶存储的位置
        Seat curSeat = s.top();

        // 走到边界
        if(curSeat.m_iX < 0 || curSeat.m_iY < 0
                || curSeat.m_iX > m_iRow || curSeat.m_iY > m_iCol){
            return false;
        }

        // 将走过的路标记为2
        m_ppMap[curSeat.m_iX][curSeat.m_iY] = 2;

        //找到出口
        if(curSeat == end){
            return true;
        }
        // 往左走
        Seat left(curSeat.m_iX, curSeat.m_iY - 1);
        if(isPass(left)){
            s.push(left);
            continue;
        }
        // 往上走
        Seat top(curSeat.m_iX - 1, curSeat.m_iY);
        if(isPass(top)){
            s.push(top);
            continue;
        }
        // 往右走
        Seat right(curSeat.m_iX, curSeat.m_iY + 1);
        if(isPass(right)){
            s.push(right);
            continue;
        }
        // 往下走
        Seat down(curSeat.m_iX + 1, curSeat.m_iY);
        if(isPass(down)){
            s.push(down);
            continue;
        }

        // 运行到此处说明 每个方向都没有路可走 是死路标记为3
        m_ppMap[curSeat.m_iX][curSeat.m_iY] = 3;
        s.pop();
    }

    return true;
}

void Maze::PrintMap() {
    for(int index_row = 0; index_row < m_iRow; index_row++){
        for(int index_col = 0; index_col < m_iCol; index_col++){
            cout << m_ppMap[index_row][index_col] << " ";
        }
        cout << endl;
    }
    cout << endl;
}

Maze::~Maze() {
   for (int i = 0; i < m_iRow; ++i  )
    {
        delete[] m_ppMap[i];
    }
    delete[] m_ppMap;
    m_ppMap = NULL;
}

bool Maze::isPass(Seat& entry) {

    // 边界
    if(entry.m_iX < 0 || entry.m_iY < 0
            || entry.m_iX >= m_iRow || entry.m_iY >= m_iCol){
        return false;
    }

    if(m_ppMap[entry.m_iX][entry.m_iY] == 0){
        return true;
    }

    return false;
}
main.cpp
#include <iostream>
#include <string>
#include "Maze.h"

using namespace std;

int main() {

    Maze m1("src/map.txt");
    Seat start(0,8); // 开始坐标
    Seat end(9,2); // 结束坐标
    stack<Seat> s;
    m1.PassMaze(s, start, end);
    m1.PrintMap();

    cout << "走过的坐标:" << endl;
    while(!s.empty()){
        Seat temp = s.top();
        cout << "(" << temp.m_iX <<","<< temp.m_iY << ")"<< ",";
        s.pop();
    }

    return 0;
}

运行结果

图片描述

相关文章:

  • Vue | 一个支持数据抓取的JSON树组件
  • css + css3技术总结报告
  • JDK1.8环境下依然报错 Unsupported major.minor version 52.0
  • 在SpringBoot中使用FluentValidator验证插件
  • Nginx学习之开启Gzip压缩提升页面加载速度
  • 10.系统设计
  • Vue实现简单选项卡
  • Bzoj4872: [Shoi2017]分手是祝愿
  • android开发 获取logcat日志并记录(方便离线调试)
  • 微服务概述之架构演变
  • 数据分区------《Designing Data-Intensive Applications》读书笔记9
  • MySQL数据库锁定机制
  • mybatis架构分析
  • SQL必知必会笔记
  • 栈------表达式求值
  • 自己简单写的 事件订阅机制
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • 2017 年终总结 —— 在路上
  • Bootstrap JS插件Alert源码分析
  • C++类的相互关联
  • CentOS从零开始部署Nodejs项目
  •  D - 粉碎叛乱F - 其他起义
  • ES6核心特性
  • Hexo+码云+git快速搭建免费的静态Blog
  • javascript 哈希表
  • Promise初体验
  • Redis 懒删除(lazy free)简史
  • 浮动相关
  • 判断客户端类型,Android,iOS,PC
  • 区块链将重新定义世界
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 微信小程序开发问题汇总
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • ![CDATA[ ]] 是什么东东
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • $forceUpdate()函数
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (安卓)跳转应用市场APP详情页的方式
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (九)信息融合方式简介
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • .bat批处理(一):@echo off
  • .NET : 在VS2008中计算代码度量值
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .NET企业级应用架构设计系列之技术选型
  • .Net中ListT 泛型转成DataTable、DataSet
  • @Valid和@NotNull字段校验使用