简体   繁体   English

为什么我的递归方法基本情况没有返回应有的布尔值?

[英]Why isn't my recursive method base case not returning a Boolean as it should be?

I have written a method that solves a given text editor maze through stacks and recursion, and it solves mazes.我写了一个方法,通过堆栈和递归解决给定的文本编辑器迷宫,它解决了迷宫。 However, my issue is that when the maze given is unsolvable as in it is literally impossible to be solved because of the walls of the maze, it's almost as if my base case is being skipped over and not returning false.然而,我的问题是,当给出的迷宫无法解决时,因为迷宫的墙壁实际上无法解决,这几乎就像我的基本案例被跳过而不返回错误。 Here is the code这是代码

 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
    }

As you can see, there are two base cases.如您所见,有两种基本情况。 One returns true - the maze is solved.一个返回true - 迷宫解决了。 And the other returns false - the maze is unsolvable.另一个返回 false - 迷宫无法解决。 The code for my isEmpty() method is as such:我的 isEmpty() 方法的代码如下:

public boolean isEmpty() {
        if(head == null){
            return true;
        }
        return false;
    }

It returns false by checking if the stack is empty.它通过检查堆栈是否为空来返回 false。 For example, if the maze runner runs into a wall and turns around it will leave an x in the text editor like so:例如,如果迷宫跑步者撞到一堵墙并转身,它将在文本编辑器中留下一个 x,如下所示:

 0123456
0HHHHHHH
1ooooxxH
2HHHoHxH
3H  oHxH
4H HoHHH
5H Hoooo
6HHHHHHH

The maze starts at 6,5;迷宫从 6,5 开始; and ends at 0,1.并在 0,1 处结束。 This is solvable.这是可以解决的。 The x's represent a failed route, the o's represent the path from start to finish. x 代表失败的路线,o 代表从开始到结束的路径。

In this next example maze, it is impossible to finish when the code would start at 7,6.在下一个示例迷宫中,当代码从 7,6 开始时不可能完成。

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

It would attempt to move left twice, leaving x's, then the stack would pop until there is no stack and the top of the stack is pointing towards null.它会尝试向左移动两次,留下 x,然后堆栈会弹出,直到没有堆栈并且堆栈顶部指向 null。 But my base case code is being skipped over, it SHOULD BE testing if the stack is empty before trying to pop the empty stack, and if it is, then returning false.但是我的基本情况代码被跳过,它应该在尝试弹出空堆栈之前测试堆栈是否为空,如果是,则返回false。 But it isn't.但事实并非如此。 Any help please?请问有什么帮助吗?

First of all, lets try to understand the problem statement first.首先,让我们先试着理解问题陈述。 We are trying to find a possible path from source to target using depth first approach here.我们试图在这里使用深度优先方法找到从源到目标的可能路径。

There is one major flaw in the algorithm which is around the lines算法中有一个主要缺陷是围绕线

        // 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);
            }
        }

consider we are currently at point (2,2) and have an option to move in either of the 4 directions ie (1,2) , (3,2) , (1,3) , (2,1).考虑我们目前处于 (2,2) 点,并且可以选择向 4 个方向之一移动,即 (1,2) , (3,2) , (1,3) , (2,1)。

As per your logic.按照你的逻辑。 we move in up direction first (1,2)我们首先向上移动 (1,2)

There could be 2 possibilities.可能有2种可能性。

  1. You find a path from this point (returns true)你从这一点找到一条路径(返回真)
  2. You don't find a path and want to continue search to other three options.您没有找到路径并希望继续搜索其他三个选项。 (returns false) (返回假)

Your code currently won't explore further options if the path leads to a failure due to the return statement如果路径由于 return 语句导致失败,您的代码目前不会探索更多选项

return findPath(newCur, finish);

This issue boils down to premature exit from the method before all operations are finished.这个问题归结为在所有操作完成之前过早退出方法。

the following stack cleanup must be called before any return statement from the method which is currently called in only one of the scenarios必须在当前仅在其中一种情况下调用的方法的任何 return 语句之前调用以下堆栈清理

// 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

I still did not understand the usage of explicit stack here completely.我还是没有完全理解这里显式堆栈的用法。 as recursion solves the similar problem which you are trying to solve using a stack.However, I would like to suggest improvements around the following lines.因为递归解决了您尝试使用堆栈解决的类似问题。但是,我想建议围绕以下几行进行改进。

// 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;
                }

            }
        }

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

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