迷宫遍历递归,打印每个完整路径

时间:2015-06-06 01:04:10

标签: c++ algorithm

我试图遍历一个迷宫并产生所有有效路径。迷宫总是从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;
}

1 个答案:

答案 0 :(得分:0)

这里的堆栈是&#39; generate_all_paths&#39;功能尚未使用。在给定的实现中,堆栈在任何给定时间最多包含一个元素。不是每次找到路径时都打印路径,只需保持堆栈全局并将新路径推送到它,然后在到达目标时立即打印整个堆栈,然后在函数末尾从堆栈中删除元素,就像你实际穿越迷宫一样,如何走回叉点。

#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的函数来打印堆栈