【问题标题】:JAVA rat in a maze DFS using stack and no node使用堆栈和无节点的迷宫 DFS 中的 JAVA 大鼠
【发布时间】:2021-11-14 12:36:53
【问题描述】:

我是一名学生,正在学习 JAVA。 我确实为 DFS(迷宫中的老鼠)编写了代码,我需要使用堆栈。我不想要 Node 类,我的迷宫只是最终的。 [0][0] 是开始,[5][5] 是退出,其中有'e'。

所以,这是我的代码,但如果我运行此代码,则 (1, 3), (2, 1) 之间存在声誉。 为什么这段代码失败了?

import java.util.Stack;

public class MazeSearch {

public static final int N = 6;
boolean[][] isVisited = new boolean[N][N];

public static int[][] maze = {
        {0, 1, 1, 1, 1, 1},
        {0, 0, 1, 0, 0, 1},
        {1, 0, 0, 0, 1, 1},
        {1, 0, 1, 0, 1, 1},
        {1, 0, 1, 0, 0, 1},
        {1, 1, 1, 1, 0, 'e'},               
};



public static void main(String[] args) {    
    
    if (dfs(maze, 0, 0))
        System.out.println("Success!");
    else
        System.out.println("Failed!");
    
}

public static boolean isValid(int m[][], int x, int y) {
    
    if (x< 0 || y<0 || x>= N || y>= N)
        return false;
    else
        return (m[y][x] == 0 || m[y][x] == 2);
        
    
}

public static boolean dfs(int m[][], int x, int y) {        
    
    Stack<Integer> stack = new Stack<Integer>();
    
    stack.push(x);
    stack.push(y);
    
    while(!stack.isEmpty())
    {
        int curx = stack.pop();
        int cury = stack.pop();
        
        System.out.printf("(" + curx + " " + cury + ")" + " -> ");
        
        if (m[cury][curx] == 2)
        {
            System.out.println("dfs searching complete!");
            return true;
        }
        else
        {
            m[cury][curx] = ',';
            
            if (isValid(m, curx, cury-1)) {
                stack.push(curx);
                stack.push(cury-1);
            }
            else if (isValid(m, curx, cury+1)) {
                stack.push(curx);
                stack.push(cury+1);
            }
            else if (isValid(m, curx-1, cury)) {
                stack.push(curx-1);
                stack.push(cury);
            }
            else if (isValid(m, curx+1, cury)) {
                stack.push(curx+1);
                stack.push(cury);
            }
            System.out.printf("content of stack (now): (%d, %d)\n", curx, cury);
        }
        
    }
    
    return false;
    }

}

编辑:现在我修复了一些东西,效果很好。

【问题讨论】:

    标签: java search depth-first-search maze


    【解决方案1】:

    一些注意事项:

    1. 堆栈工作后进先出 (LIFO),因此,因为您对xy 坐标使用相同的堆栈,请注意poping 应该在这种情况下与pushing 相反,即如果您首先push x 坐标然后y 然后y 预计将在顶部,所以你应该pop @987654330先是@坐标,然后是x
    2. 对于每个访问的网格单元,您只将一个相邻的网格单元推入堆栈。但是每个网格单元有 4 个邻居,而不是 1 个。所以你应该检查每次访问的所有邻居,这意味着转换:
      if (isValid(m, curx, cury-1)) {
          stack.push(curx);
          stack.push(cury-1);
      }
      else if (isValid(m, curx, cury+1)) {
          stack.push(curx);
          stack.push(cury+1);
      }
      else if (isValid(m, curx-1, cury)) {
          stack.push(curx-1);
          stack.push(cury);
      }
      else if (isValid(m, curx+1, cury)) {
          stack.push(curx+1);
          stack.push(cury);
      }
      
      对此:
      if (isValid(m, curx, cury-1)) {
          stack.push(curx);
          stack.push(cury-1);
      }
      if (isValid(m, curx, cury+1)) {
          stack.push(curx);
          stack.push(cury+1);
      }
      if (isValid(m, curx-1, cury)) {
          stack.push(curx-1);
          stack.push(cury);
      }
      if (isValid(m, curx+1, cury)) {
          stack.push(curx+1);
          stack.push(cury);
      }
      
      (基本上去掉了elses)。
    3. 您不使用isVisited 数组。对于您访问的每个网格单元格,您可以将对应的位置设置为true,并在isValid逻辑中使用此信息,以便如果给定的单元格已经访问过,则从中返回false

    总结笔记,如下示例代码:

    import java.util.Stack;
    
    public class MazeSearch {
    
        public static final int N = 6;
        private static boolean[][] isVisited = new boolean[N][N];
    
        public static char[][] maze = {
            {'0', '1', '1', '1', '1', '1'},
            {'0', '0', '1', '0', '0', '1'},
            {'1', '0', '0', '0', '1', '1'},
            {'1', '0', '1', '0', '1', '1'},
            {'1', '0', '1', '0', '0', '1'},
            {'1', '1', '1', '1', '0', 'e'}};
    
        public static void main(String[] args) {
            if (dfs(maze, 0, 0)) {
                System.out.println("Success!");
            } else {
                System.out.println("Failed!");
            }
    
        }
    
        public static boolean isValid(char m[][], int x, int y) {
            if (x < 0 || y < 0 || x >= N || y >= N)
                return false;
            if (isVisited[y][x])
                return false;
            return (m[y][x] == '0' || m[y][x] == '2');
        }
    
        public static boolean dfs(char m[][], int x, int y) {
    
            Stack<Integer> stack = new Stack<>();
    
            stack.push(x);
            stack.push(y);
    
            while (!stack.isEmpty()) {
                //Changed the pop sequence!
                int cury = stack.pop();
                int curx = stack.pop();
    
                System.out.println("Visiting [" + cury + ", " + curx + "]...");
    
                if (m[cury][curx] == '2') {
                    System.out.println("dfs searching complete!");
                    return true;
                } else {
                    m[cury][curx] = ',';
                    isVisited[cury][curx] = true;
    
                    if (isValid(m, curx, cury - 1)) {
                        stack.push(curx);
                        stack.push(cury - 1);
                    }
                    if (isValid(m, curx, cury + 1)) {
                        stack.push(curx);
                        stack.push(cury + 1);
                    }
                    if (isValid(m, curx - 1, cury)) {
                        stack.push(curx - 1);
                        stack.push(cury);
                    }
                    if (isValid(m, curx + 1, cury)) {
                        stack.push(curx + 1);
                        stack.push(cury);
                    }
                    //System.out.printf("content of stack (now): (%d, %d)\n", curx, cury);
                }
    
            }
            return false;
        }
    }
    

    尝试将字符从'0' 更改为'2'(在迷宫中),您将看到成功 消息(因为您找到了它)。否则,您将在控制台中看到所有索引都已访问,但由于找不到 '2',因此您将按预期看到 Failure 消息。

    【讨论】:

    • 感谢您的回答。现在我意识到我错过了堆栈弹出顺序和 4 如果问题需要推送更多相邻单元格。最后,我没有使用 isVisited 数组。谢谢你。祝你有美好的一天。
    • 没问题@nojob。也有美好的一天。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 2021-08-28
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多