Java 为什么不是';我的递归方法的基本情况是否不返回应该返回的布尔值?

Java 为什么不是';我的递归方法的基本情况是否不返回应该返回的布尔值?,java,recursion,stack,maze,Java,Recursion,Stack,Maze,我写了一个方法,通过堆栈和递归来解决给定的文本编辑器迷宫,它解决了迷宫。然而,我的问题是,当给定的迷宫无法解决时,因为迷宫的墙壁,它实际上是不可能解决的,这几乎就像我的基本情况被跳过,而不是返回false。这是密码 private boolean findPath(MazeLocation cur, MazeLocation finish) { int row = cur.row; int col = cur.col; mazeToSolve.s

我写了一个方法,通过堆栈和递归来解决给定的文本编辑器迷宫,它解决了迷宫。然而,我的问题是,当给定的迷宫无法解决时,因为迷宫的墙壁,它实际上是不可能解决的,这几乎就像我的基本情况被跳过,而不是返回false。这是密码

 private boolean findPath(MazeLocation cur, MazeLocation finish) {
        int row = cur.row;
        int col = cur.col;
        mazeToSolve.setChar(row, col, 'o');
        fileWriter.println("\n"+mazeToSolve.toString());
        char strX = 'X';
        char strH = 'H';

        // First ,we need to scan the 4 directions around current location to see where to go
        MazeLocation up = new MazeLocation(row-1, col);
        MazeLocation down = new MazeLocation(row+1, col);
        MazeLocation right = new MazeLocation(row, col+1);
        MazeLocation left = new MazeLocation(row, col-1);

        // BASE CASE - WHEN WE'VE REACHED FINISH COORDINATES
        if(cur.row == finish.row && cur.col == finish.col){
            return true;
        }
        // SECOND BASE CASE - IF MAZE ISNT SOLVABLE
        if (path.isEmpty() == true){ // if the path is empty, then there is no solution.
            return false;
        }

        // Check if we can go up
        if(up.getRow() >= 0){
            if(mazeToSolve.getChar(up.getRow(), up.getCol()) == ' '){
                row = up.getRow();
                col = up.getCol();
                MazeLocation newCur = new MazeLocation(row, col);
                path.push(newCur);
                return findPath(newCur, finish);
            }
        }

        // Check if we can go down
        if(down.getRow() < mazeToSolve.getRows()){
            if(mazeToSolve.getChar(down.getRow(), down.getCol()) == ' '){
                row = down.getRow();
                col = down.getCol();
                MazeLocation newCur = new MazeLocation(row, col);
                path.push(newCur);
                return findPath(newCur, finish);
            }
        }

        // Check if we can go right
        if(right.getCol() < mazeToSolve.getCols()){
            if(mazeToSolve.getChar(right.getRow(), right.getCol()) == ' '){
                row = right.getRow();
                col = right.getCol();
                MazeLocation newCur = new MazeLocation(row, col);
                path.push(newCur);
                return findPath(newCur, finish);
            }
        }

        // Check if we can go left
        if(left.getCol() >= 0){
            if(mazeToSolve.getChar(left.getRow(), left.getCol()) == ' '){
                row = left.getRow();
                col = left.getCol();
                MazeLocation newCur = new MazeLocation(row, col);
                path.push(newCur);
                return findPath(newCur, finish);
            }
        }

         // If we cant do any of the above then we need to backtrack by popping the top of stack
         // and leaving X's until we can move up, down, left, or right again.
         MazeLocation newCur = new MazeLocation(row, col);
         path.pop(); // popping the cur where we are putting the x
         mazeToSolve.setChar(row, col, 'x'); // putting the x
         return findPath(path.top(), finish); // now we need to return to the position where the stack is NOW after the pop
    }
通过检查堆栈是否为空,返回false。例如,如果迷宫跑步者撞到墙上并转过身,它将在文本编辑器中留下一个x,如下所示:

 0123456
0HHHHHHH
1ooooxxH
2HHHoHxH
3H  oHxH
4H HoHHH
5H Hoooo
6HHHHHHH
迷宫从6,5开始;并在0,1处结束。这是可以解决的。x代表失败的路由,o代表从开始到结束的路径

在下一个示例中,代码从7,6开始时不可能完成

HHHHHHH
      H
HHH H H
H   H H
H HHHHH
H H    
HHHHHHH

它将尝试向左移动两次,留下x,然后堆栈将弹出,直到没有堆栈并且堆栈顶部指向null。但是我的基本案例代码被跳过了,它应该在尝试弹出空堆栈之前测试堆栈是否为空,如果为空,则返回false。但事实并非如此。有什么帮助吗?

首先,让我们先试着理解问题陈述。我们正在尝试使用深度优先的方法找到从源到目标的可能路径

在算法中有一个主要的缺陷,它围绕着行

        // Check if we can go up
        if(up.getRow() >= 0){
            if(mazeToSolve.getChar(up.getRow(), up.getCol()) == ' '){
                row = up.getRow();
                col = up.getCol();
                MazeLocation newCur = new MazeLocation(row, col);
                path.push(newCur);
                return findPath(newCur, finish);
            }
        }

        // Check if we can go down
        if(down.getRow() < mazeToSolve.getRows()){
            if(mazeToSolve.getChar(down.getRow(), down.getCol()) == ' '){
                row = down.getRow();
                col = down.getCol();
                MazeLocation newCur = new MazeLocation(row, col);
                path.push(newCur);
                return findPath(newCur, finish);
            }
        }
这个问题归结为在所有操作完成之前过早退出方法

在当前仅在一个场景中调用的方法的任何返回语句之前,必须调用以下堆栈清理

// If we cant do any of the above then we need to backtrack by popping the top of stack
// and leaving X's until we can move up, down, left, or right again.

path.pop(); // popping the cur where we are putting the x
我仍然不完全理解显式堆栈在这里的用法。因为递归解决了您正试图使用堆栈解决的类似问题, 我想就以下几点提出改进建议

// Check if we can go up
        if(up.getRow() >= 0){
            if(mazeToSolve.getChar(up.getRow(), up.getCol()) == ' '){
                row = up.getRow();
                col = up.getCol();
                MazeLocation newCur = new MazeLocation(row, col);
                path.push(newCur);
                boolean val =  findPath(newCur, finish);
                if(val){
                  path.pop();
                  return true;
                }

            }
        }


这似乎没有编译,因为“path”不是declaredStart with(7,6)迷宫上有任何位置吗?它是编译的,path是在另一个方法中声明的堆栈对象。你说Eklavya是什么意思?你在为你的项目使用一个特定的库吗?不,没有什么特别的@bdzzaid,函数肯定出了什么问题,让它跳过为isEmpty()返回false。我单独测试了isEmpty(),它可以工作。我感谢您的帮助,但它对我没有帮助。同样,我的代码是这样工作的:迷宫开始,迷宫在每个方向上搜索一条路径,它沿着可用的开放路径,直到一个死胡同或它到达迷宫的终点。它使用堆栈完成此操作,每个坐标都添加到堆栈中。如果到达死胡同,它将弹出堆栈顶部,直到有另一条路径可用。我的问题是,如果一个迷宫实际上不可能完成,比如路径被四面围住,没有方向,我的方法不会返回“false”,这意味着它找不到解决方案。我的mazerunner方法适用于每个可能有解决方案的迷宫,算法不会被破坏。如果没有真正的解决方案,我的方法会给我一个空堆栈异常,因为它试图删除空堆栈的顶部。此外,您的答案包含的固定代码将在第一次向上移动后停止任何递归
// If we cant do any of the above then we need to backtrack by popping the top of stack
// and leaving X's until we can move up, down, left, or right again.

path.pop(); // popping the cur where we are putting the x
// Check if we can go up
        if(up.getRow() >= 0){
            if(mazeToSolve.getChar(up.getRow(), up.getCol()) == ' '){
                row = up.getRow();
                col = up.getCol();
                MazeLocation newCur = new MazeLocation(row, col);
                path.push(newCur);
                boolean val =  findPath(newCur, finish);
                if(val){
                  path.pop();
                  return true;
                }

            }
        }