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

一旦满足基本情况,如何让这个递归方法停止?

章晗日
2023-03-14

我有一个迷宫,我必须用递归来解。迷宫必须在找到开放路径的地方放置一个X(我的代码就是这样做的)。它必须这样做,直到使用递归调用到达出口为止(我的代码就是这样做的,下面描述的除外)。它还必须在到达死胡同的地方放置一个O,将操作系统拉回到“正确”路径,然后沿着新路径继续求解(我的代码就是这样做的)。

然而,一旦到达迷宫的末端,它就必须求解一个新的迷宫(原始迷宫,转置)。我的问题如下:

一旦我到达迷宫的尽头,我就会收到一个IndexOutOfBoundsException。这是意料之中的;我不能在迷宫边界之外继续测试!也就是说,如果我尝试以任何方式测试和避免异常,递归方法调用仍然在调用堆栈上,结果是我的方法继续编写O,一直写回起点。

一旦到达出口,我想简单地中止或退出。我以为我的基本情况会处理这一点,但它没有;它继续前进。我不能从那个点执行任何返回,包括通过一个基本用例或者通过方向检查期间的测试,因为返回创建了一种情况,其中调用栈开始解析在那个点之前的所有调用。最终结果是Os出现在不应该出现Os的地方,递归方法永远不会“返回”,直到调用堆栈被清除。

将方法更改为bool返回类型不起作用。我试过了。我得到同样的结果。要么我得到一个异常,要么我得到被Os覆盖的x,从最后的死胡同,通过出口,一直回到起点。

迷宫和我的代码在下面。请帮忙;我已经连续六个小时都在处理这个问题,我完全被难住了。

char[,] maze1 = {
            { '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#' },
            { '#', '.', '.', '.', '#', '.', '.', '.', '.', '.', '.', '#' },
            { '#', '.', '#', '.', '#', '.', '#', '#', '#', '#', '.', '#' },
            { '#', '#', '#', '.', '#', '.', '.', '.', '.', '#', '.', '#' },
            { '#', '.', '.', '.', '.', '#', '#', '#', '.', '#', '.', '.' },
            { '#', '#', '#', '#', '.', '#', '.', '#', '.', '#', '.', '#' },
            { '#', '.', '.', '#', '.', '#', '.', '#', '.', '#', '.', '#' },
            { '#', '#', '.', '#', '.', '#', '.', '#', '.', '#', '.', '#' },
            { '#', '.', '.', '.', '.', '.', '.', '.', '.', '#', '.', '#' },
            { '#', '#', '#', '#', '#', '#', '.', '#', '#', '#', '.', '#' },
            { '#', '.', '.', '.', '.', '.', '.', '#', '.', '.', '.', '#' },
            { '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#' }
        };

递归方法:

private void MazeTraversal(char[,] maze, int row, int col)
    {
        if (row < maze.GetLength(0) && col < maze.GetLength(1))
        {
            maze[row, col] = 'X';
            Console.Write(writer.WriteMaze(maze));
            System.Threading.Thread.Sleep(250);

            #region GoNorth
            // GoNorth
            if (maze[(row - 1), col] == '.')
            {
                MazeTraversal(maze, row - 1, col);
                if (wroteAnO)
                {
                    Console.Write(writer.WriteMaze(maze));
                    wroteAnO = false;
                    System.Threading.Thread.Sleep(250);
                }
            }
            #endregion

            #region GoSouth
            if (maze[(row + 1), col] == '.')
            {
                MazeTraversal(maze, row + 1, col);
                if (wroteAnO)
                {
                    Console.Write(writer.WriteMaze(maze));
                    wroteAnO = false;
                    System.Threading.Thread.Sleep(250);
                }
            }
            #endregion

            #region GoEast

            if (maze[row, (col + 1)] == '.')
            {
                MazeTraversal(maze, row, col + 1);
                if (wroteAnO)
                {
                    Console.Write(writer.WriteMaze(maze));
                    wroteAnO = false;
                    System.Threading.Thread.Sleep(250);
                }
            }
            #endregion

            #region GoWest
            if (maze[row, (col - 1)] == '.')
            {
                MazeTraversal(maze, row, col - 1);
                if (wroteAnO)
                {
                    Console.Write(writer.WriteMaze(maze));
                    wroteAnO = false;
                    System.Threading.Thread.Sleep(250);
                }
            }
            #endregion


        }
        // if nothing contains a ".", we can't go in any direction. Draw an "O"
        maze[row, col] = 'O';
        wroteAnO = true;
    }

共有1个答案

吕衡
2023-03-14

您的问题可能是永远无法达到等于数组长度的索引(因为最大索引始终是长度-1),因此总是执行条件。尝试更改if(row

 类似资料:
  • 我试图理解这段代码,它返回传递给它的的所有可能组合: 在这里,我尝试了这个样本输入: 在这里,我似乎无法理解递归最终将如何停止并返回,因为函数肯定没有任何指针在列表中移动,在每次调用时,当它满足基本情况时,它返回。根据我的说法,它将调用函数无限,并且永远不会自行停止。或者可能是我错过了什么? 另一方面,take 在完成递归调用后返回返回所有计算后,仅返回的前 个元素。那么,实际上递归如何满足这里的

  • 我写了一个到达基本情况的方法(我可以告诉你,因为它打印了print语句),但是它会循环返回null(在方法的结尾)。为什么我的方法没有在基本情况下停止? 编辑:此外,如果一个对象不存在于我的BST中,它不会返回null。我得到了一个空指针异常,这是不应该发生的,因为或语句

  • 我花了一段时间研究以下算法: 你会得到不同面额的硬币和总金额。写一个函数来计算你需要的最少数量的硬币来组成这个数量。如果这些硬币的任何组合都不能弥补这个金额,返回-1。 例1:币=[1,2,5],金额=113 (11 = 5 5 1) 例2:硬币=[2],金额=3返回-1。 注意:你可以假设每种硬币的数量是无限的。 这可能不是解决问题的最有效方法,但我想我可以通过尝试每一个硬币并每次尝试启动一个新

  • 问题内容: 我在使用Java中的基本递归问题时遇到了很多麻烦;任何指针都很棒。 “写一种静态递归方法来打印出几何序列的第n个项:2、6、18、54。” 据我所知,我应该在代码中的某处递归地将某物乘以3,但我一直在努力寻找方法。我知道我需要终止声明,但是何时发生?我需要帮手方法吗? 问题答案: 一个递归函数是一个函数,它的实现引用自身。以下是一些有趣的示例: 解决问题的方法: 编辑 : 上面的类使用

  • 我仍在尝试实现2-3个手指树,并取得了良好的进展(存储库)。在做一些基准测试时,我发现当树非常大时,我非常基本的toList会导致堆栈溢出异常。起初,我看到了一个简单的修复方法,并将其设置为尾部递归。 不幸的是,事实证明,toList不是罪魁祸首,但viewr是: 寻找唯一的递归调用很明显,这不是尾部递归。不知何故,我希望这个问题不会存在,因为这个调用被包装在一个类似于连续的延迟中。 我听说并读过

  • 我想澄清一下O(N)函数。我正在使用SICP。 考虑书中生成伪代码递归过程的阶乘函数: 我不知道如何测量步数。也就是说,我不知道“步骤”是如何定义的,所以我使用书中的语句来定义步骤: 因此,我们可以计算n!通过计算(n-1)!将结果乘以n。 我想这就是他们所说的一步。对于一个具体的例子,如果我们跟踪(阶乘5), 阶乘(1)=1=1步(基本情况-恒定时间) 阶乘(2)=2*阶乘(1)=2步 阶乘(3