繁体   English   中英

使用堆栈和无节点的迷宫 DFS 中的 JAVA 老鼠

[英]JAVA rat in a maze DFS using stack and no node

我是一名学生,正在学习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;
    }

}

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

一些注意事项:

  1. 堆栈采用后进先出(LIFO),因此,因为您对xy坐标使用相同的堆栈,请注意,在这种情况下, pop应该与push相反,即如果您push x首先坐标然后y然后y预计在顶部,所以你应该先pop y坐标,然后是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); }
    (基本上删除else s)。
  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'因此您将看到预期的失败消息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM