当前位置: 首页 > 知识库问答 >
问题:

为什么我的递归方法基例没有按预期返回布尔值?

华永逸
2023-03-14

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

 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 -迷宫是不可解的。我的isEmpty()方法的代码如下:

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

它通过检查堆栈是否为空来返回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。但事实并非如此。请帮忙吗?

共有1个答案

董喜
2023-03-14

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

在算法中有一个主要的缺陷是围绕线的

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

假设我们目前位于点(2,2),并且可以选择向4个方向移动,即(1,2),(3,2),(1,3),(2,1)。

按照你的逻辑。我们先向上移动(1,2)

可能有两种可能性。

    < li >从这一点找到一条路径(返回true) < li >您没有找到路径,想继续搜索其他三个选项。(返回false)

如果路径由于返回语句导致失败,您的代码目前不会探索进一步的选项

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

            }
        }

 类似资料:
  • 问题内容: 我有一个自称的函数: 现在,如果我只输入,则一切正常: 但是,如果我输入其他内容,然后输入 ,则会得到以下信息: 我不知道为什么要回来,因为它应该只回来。这None是哪里来的,我该如何修复我的功能? 问题答案: 之所以返回,是None因为当你递归调用它时: ..你不返回该值。 因此,当确实发生递归时,返回值将被丢弃,然后你就无法使用该函数了。退出函数的末尾意味着隐式返回None,就像这

  • 我想写返回true的Python函数一个字符串s是回文,也就是等于它的反。例如,“赛车”和“abba”是回文。到目前为止,这是我不成功的尝试。 当我告诉我的函数返回相反的结果时,我没有问题,但是,我不知道应该如何进行比较才能返回一个布尔值。 使用上面的函数会产生以下错误 现在我完全理解为什么会产生上述错误。这是因为一些递归函数返回一个boool并尝试将其添加到字符串中;但是我做不到的是如何避免这个

  • 好的,我的问题是关于布尔返回。对于我的Comp-Sci作业,我必须使用多种方法制作一个课程注册程序,其中之一就是添加课程方法。基本上,在目录中搜索类,如果匹配,则将其添加到学生计划中,并返回布尔值true。我这么做了,但出于某种原因,这给了我一个错误。以下是代码: 为什么它不能识别布尔返回值?是因为我把它们放在了一个圈里吗?

  • 我觉得这给了我很小的灵活性每当我使用这个函数。使用此函数时,我通常会查找元素的第一次出现,但它只返回,我发现这一点有些欠缺。 使用此函数的主要原因是每当找到元素时,都会循环,因此使用会失去作用,因为不会短路。是相同的。 我是遗漏了什么,还是必须使用循环来获取JavaScript中的第一个匹配元素?

  • 我正在创建一个进行线性探测以查找键索引的哈希图。如果键已经在索引中,我想增加它的值,而不是向新索引添加一个。 例如,如果我得到字符串“五,五,五”的字数,我的输出是五1,五1,五1,而不是五3。 我认为一定是我的 containsKey 方法,它使用 get 方法来检查我的密钥是否已在映射中。下面是我的Hashmap.java类。