【问题标题】:Maze traversal with recursion what prints every full path带有递归的迷宫遍历打印每条完整路径
【发布时间】:2015-06-06 13:53:56
【问题描述】:

我正在尝试穿越迷宫并生成所有有效路径。迷宫总是从 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;
}

【问题讨论】:

    标签: c++ algorithm


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-04
      • 2011-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多