递归的迷宫遍历输出每一条完整的路径

Maze traversal with recursion what prints every full path

本文关键字:路径 一条 输出 迷宫 遍历 递归      更新时间:2023-10-16

我正在尝试遍历迷宫并产生所有有效路径。迷宫总是从s开始,所有出口都可以在最右边的任何地方墙。顶墙和底墙始终是一排排的#符号。我只能移动相邻的包含非#字符的正方形

这是一个迷宫的例子。

######
Sa#hln
#bdp##
##e#ko
#gfij#
######

这是应该打印出来的内容:

S, a, b, d, e, f, i, j, k, o

S, a, b, d, p, h, l, n

我得到S a b d e f I j k o p h l n

这是第一条路径,以及它分叉的第二条路径的一半。我将感激任何帮助。谢谢你。

#include <fstream>
#include <string>
#include <iostream>
#include <stack>
using namespace std;
//std::ifstream file("maze.txt");
string str;
string file_contents;
fstream in("maze.txt");
//check if char is not #
bool characterAt(string maze[][6], int r, int c){
    if (maze[r][c] == "#"){
        return false;
    }
    return true;
}
//check if I have been there before
bool backTrack(bool maze[][6], int r, int c){
    if (maze[r][c] == false){
        return true;
    }
    return false;
}
//check if my move is in bounds.
bool validMove(int r, int c){
    if (r - 1 < 0 || r + 1 > 6 ||
        c - 1 < 0 || c + 1 > 6){
        return false;
    }
    return true;
}`
//check if there is a next move
bool thereIsNextMove(string maze[][6], bool bmaze[][6], int rows, int columns){
    if (validMove(rows - 1, columns) && backTrack(bmaze, rows - 1, columns) && characterAt(maze, rows - 1, columns) ||
        validMove(rows + 1, columns) && backTrack(bmaze, rows + 1, columns) && characterAt(maze, rows + 1, columns) ||
        validMove(rows, columns - 1) && backTrack(bmaze, rows, columns - 1) && characterAt(maze, rows, columns - 1) ||
        validMove(rows, columns + 1) && backTrack(bmaze, rows, columns + 1) && characterAt(maze, rows, columns + 1)){
        return true;
    }
    return false;
}
void generate_all_paths(string maze[][6], bool bmaze[][6], int rows, int columns){
    int y = rows;
    int x = columns;
    string path = maze[y][x];
    stack<string> s;
    if (thereIsNextMove(maze, bmaze, y, x) || x == 5){
        s.push(path);
        cout << s.top();
        s.pop();
    }
    if (validMove(y - 1, x) && characterAt(maze, y - 1, x) && backTrack(bmaze, y - 1, x)){
        bmaze[y][x] = true;
        generate_all_paths(maze, bmaze, y - 1, x);
    }
    if (validMove(y + 1, x) && characterAt(maze, y + 1, x) && backTrack(bmaze, y + 1, x)){
        bmaze[y][x] = true;
        generate_all_paths(maze, bmaze, y + 1, x);
    }
    if (validMove(y, x - 1) && characterAt(maze, y, x - 1) && backTrack(bmaze, y, x - 1)){
        bmaze[y][x] = true;
        generate_all_paths(maze, bmaze, y, x - 1);
    }
    if (validMove(y, x + 1) && characterAt(maze, y, x + 1) && backTrack(bmaze, y, x + 1)){
        bmaze[y][x] = true;
        generate_all_paths(maze, bmaze, y, x + 1);
    }
}

int main(){
    while (getline(in, str))
    {
        file_contents += str;
        //file_contents.push_back('n');
    }
    string maze[6][6];
    for (int row = 0; row < 6; row++){
        for (int col = 0; col < 6; col++){
            char mazeChar = file_contents.at(6 * row + col);
            maze[row][col] = mazeChar;
        }
    }
    bool bmaze[6][6];
    for (int brow = 0; brow < 6; brow++){
        for (int bcol = 0; bcol < 6; bcol++){
            bmaze[brow][bcol] = false;
        }
    }
    string path;
    generate_all_paths(maze, bmaze, 1, 0);
    int age;
    cin >> age;
    return 0;
}

这里'generate_all_paths'函数中的堆栈根本没有被使用。在给定的实现中,堆栈在任何给定时间最多只包含一个元素。与其每次找到路径都打印路径,不如让堆栈保持全局,并将新路径推送到它,然后在到达目的地时立即打印整个堆栈,然后在函数结束时从堆栈中删除该元素,就像你在穿越迷宫时走回分叉点一样。

#include <fstream>
#include <string>
#include <iostream>
#include <stack>
using namespace std;
//std::ifstream file("maze.txt");
string str;
string file_contents;
fstream in("maze.txt");
stack<string> s;
//check if char is not #
bool characterAt(string maze[][6], int r, int c){
    if (maze[r][c] == "#"){
        return false;
    }
    return true;
}
//check if I have been there before
bool backTrack(bool maze[][6], int r, int c){
    if (maze[r][c] == false){
        return true;
    }
    return false;
}
//check if my move is in bounds.
bool validMove(int r, int c){
    if (r - 1 < 0 || r + 1 > 6 ||
        c - 1 < 0 || c + 1 > 6){
        return false;
    }
    return true;
}
//check if there is a next move
bool thereIsNextMove(string maze[][6], bool bmaze[][6], int rows, int columns){
    if (validMove(rows - 1, columns) && backTrack(bmaze, rows - 1, columns) && characterAt(maze, rows - 1, columns) ||
        validMove(rows + 1, columns) && backTrack(bmaze, rows + 1, columns) && characterAt(maze, rows + 1, columns) ||
        validMove(rows, columns - 1) && backTrack(bmaze, rows, columns - 1) && characterAt(maze, rows, columns - 1) ||
        validMove(rows, columns + 1) && backTrack(bmaze, rows, columns + 1) && characterAt(maze, rows, columns + 1)){
        return true;
    }
    return false;
}
template < typename T > void print( const std::stack<T>& stk )
{
    struct cheat : std::stack<T> { using std::stack<T>::c ; } ;
    const auto& seq = static_cast< const cheat& >(stk).c ;
    for( const auto& v : seq ) std::cout << v << ' ' ;
    std::cout << 'n' ;
}
void generate_all_paths(string maze[][6], bool bmaze[][6], int rows, int columns){
    int y = rows;
    int x = columns;
    string path = maze[y][x];
    bool pushed = false;
    if (thereIsNextMove(maze, bmaze, y, x)){
        s.push(path);
        pushed = true;
    }
    if (x == 5){
        s.push(path);
        pushed=true;
        print(s);//printing the entire stack once a path has been found
    }
    if (validMove(y - 1, x) && characterAt(maze, y - 1, x) && backTrack(bmaze, y - 1, x)){
        bmaze[y][x] = true;
        generate_all_paths(maze, bmaze, y - 1, x);
    }
    if (validMove(y + 1, x) && characterAt(maze, y + 1, x) && backTrack(bmaze, y + 1, x)){
        bmaze[y][x] = true;
        generate_all_paths(maze, bmaze, y + 1, x);
    }
    if (validMove(y, x - 1) && characterAt(maze, y, x - 1) && backTrack(bmaze, y, x - 1)){
        bmaze[y][x] = true;
        generate_all_paths(maze, bmaze, y, x - 1);
    }
    if (validMove(y, x + 1) && characterAt(maze, y, x + 1) && backTrack(bmaze, y, x + 1)){
        bmaze[y][x] = true;
        generate_all_paths(maze, bmaze, y, x + 1);
    }
    if(pushed){
        s.pop();//removing the element from the stack like how you walk back to fork point
    }
}

int main(){
    while (getline(in, str))
    {
        file_contents += str;
        //file_contents.push_back('n');
    }
    string maze[6][6];
    for (int row = 0; row < 6; row++){
        for (int col = 0; col < 6; col++){
            char mazeChar = file_contents.at(6 * row + col);
            maze[row][col] = mazeChar;
        }
    }
    bool bmaze[6][6];
    for (int brow = 0; brow < 6; brow++){
        for (int bcol = 0; bcol < 6; bcol++){
            bmaze[brow][bcol] = false;
        }
    }
    string path;
    generate_all_paths(maze, bmaze, 1, 0);
    int age;
    cin >> age;
    return 0;
}

PS -我已经添加了一个名为print的函数来打印堆栈