【问题标题】:Recurstion stack overflow and I dont understand why递归堆栈溢出,我不明白为什么
【发布时间】:2022-11-01 23:59:49
【问题描述】:

一个大小为 NxN 的二维数组,由 1 和 0 组成。

邻居是索引的北/南/西/东的 1

递归查找数组中的索引有多少个邻居(也包括与其他邻居接触的邻居)。

对于我构建的数组,我应该得到 6,但是我得到了一个堆栈溢出异常,我不明白为什么。 下面是我的 7x7 数组,对于索引 2,5 应该返回 6 的值。

static void Main(string[] args)
        {
            int[,] arr = { {0,0,0,1,0,0,0 },{1,0,0,1,1,0,0 },{0,0,0,0,1,1,0 },{0,0,0,0,1,0,0 },{0,0,0,0,0,0,0 },{0,1,1,1,1,0,0 },{1,0,0,1,0,0,0 } };
            Console.WriteLine(Recursive(arr,2,5));
            Console.ReadLine();
        }
        static public int Recursive(int[,] arr,int x,int y) 
        {   
            if(x < 0 || y < 0 || x > arr.GetLength(0) || y > arr.GetLength(1))
            {
                return 0;
            }
            // check if a 1 has neighbors
            if (arr[x, y] == 1)
            {
              return 1 + Recursive(arr,x-1,y) +Recursive(arr, x + 1, y) + Recursive(arr, x, y -1) +Recursive(arr, x, y + 1);
            }
            else
            {
                return 0;
            }                   
        }

【问题讨论】:

  • 欢迎来到堆栈溢出!这是您开始熟悉using a debugger 的好机会。当您在调试器中单步执行代码时,哪个操作首先会产生意外结果?该操作中使用的值是什么?结果如何?预期的结果是什么?为什么?要了解有关此社区的更多信息以及我们如何为您提供帮助,请从 tour 开始并阅读 How to Ask 及其链接资源。
  • 从一个更简单的情况开始 - 一个 1x2 数组,其中两个值都设置为 1,然后使用坐标 0,0 运行调用。这将对0,1 进行递归调用。这反过来将递归调用0,0,而这又将...

标签: c# recursion


【解决方案1】:

请注意,当您计算 Recursive(arr,x,y) 时,您调用两个都Recursive(arr,x-1,y)Recursive(arr,x+1,y):

return 1 + Recursive(arr,x-1,y) +Recursive(arr, x + 1, y) + Recursive(arr, x, y -1) +Recursive(arr, x, y + 1);

在下一次递归调用中,当您尝试计算Recursive(arr, x + 1, y) 时,它会调用Recursive(arr, x + 2, y) 以及Recursive(arr, x + 1 - 1, y),即Recursive(arr, x, y)。所以你有一个恶性循环:要计算Recursive(arr,x,y),您必须计算Recursive(arr,x,y),结果是堆栈溢出

【讨论】:

  • 哦,所以它基本上是 x+1 然后在无限循环中检查 x -1 因为 x-1 是第一次调用 x+1 的人?
  • @Nitay Aqawae:是的,正是
【解决方案2】:

首先考虑最简单的输入。在这种情况下,它将是一个类似的数组

int[,] arr = { {1, 1 }}

IE。仅包含两项的数组。

  1. 从左边的第一个项目开始,这是一个,所以接下来所有的邻居都递归到。
  2. 除了右邻之外的所有元素都在数组之外,因此将被忽略。
  3. 右边的项目是 1,所以它的所有邻居都将被递归到,包括左边的项目。

    由于您最终再次处理左侧项目,因此您将继续递归,直到用完堆栈空间。

    这里的重点是您需要跟踪您已经访问过的所有点。例如,使用HashSet&lt;(int x, int y)&gt;

【讨论】:

    猜你喜欢
    • 2011-03-27
    • 2019-11-18
    • 2015-04-04
    • 2017-01-20
    • 2018-12-02
    • 2017-09-06
    • 2019-07-08
    • 2015-08-05
    • 2017-09-29
    相关资源
    最近更新 更多