【问题标题】:Recursive Stackoverflow Error递归 Stackoverflow 错误
【发布时间】:2011-12-26 18:42:23
【问题描述】:

好的,所以我正在尝试制作一个 Java 程序来解决一个 picross board,但我不断收到 Stackoverflow 错误。我目前只是自学一点Java,所以我喜欢使用我知道的东西而不是在网上寻找解决方案,尽管我的方法显然没有那么有效。我能想到解决这个问题的唯一方法是通过一种蛮力,尝试每一种可能性。问题是,我知道这个函数可以工作,因为它适用于较小尺寸的电路板,唯一的问题是对于较大的电路板,我往往会在函数完成之前出错。

所以char[][] a 只是带​​有所有 X 和 O 的游戏板。 int[][] b 是一个数组,其中包含为棋盘分配的数字,就像游戏顶部和左侧的数字一样。 isDone() 只检查棋盘是否与给定的数字匹配,shift() 向下移动一列。我不想粘贴我的整个程序,所以如果您需要更多信息,请告诉我。谢谢!

自从有人问起,我添加了 shift 的代码。 Shift 只是将一行中的所有字符向上移动一个单元格。

更新:我在想也许我的代码并没有遍历每个组合,所以它跳过了正确的答案。谁能验证这实际上是在尝试所有可能的组合吗?因为这可以解释为什么我会遇到 stackoverflow 错误。但另一方面,这要经过多少次迭代才算太多?

public static void shifter(char[][] a, int[][] b, int[] clockwork)
{
    boolean correct = true;

    correct = isDone(a, b);

    if(correct)
        return;

    clockwork[a[0].length - 1]++;

        for(int x = a[0].length - 1; x > 0; x--)
        {
            if(clockwork[x] > a.length)
            {
                shift(a, x - 1);

                clockwork[x - 1]++;
                clockwork[x] = 1;
            }

            correct = isDone(a, b);

            if(correct)
                return;
        }

    shift(a, a[0].length - 1);

    correct = isDone(a, b);

    if(correct)
        return;

    shifter(a, b, clockwork);

    return;
}

public static char[][] shift(char[][] a, int y)
{       
        char temp = a[0][y];

            for(int shifter = 0; shifter < a.length - 1; shifter++)
            {
                a[shifter][y] = a[shifter + 1][y];
            }

        a[a.length - 1][y] = temp;

    return a;
}

【问题讨论】:

  • 在多少次迭代/递归之后它会爆炸?
  • 考虑让 shifter 成为一个 void 函数,而不是返回一个 [][]。 a[][] 已经在 java 中通过引用传递。
  • 呃,我不确定它到底经历了多少次迭代。这似乎是 5x5 板的一个很好的部分。在崩溃之前它通常可以处理多少?我将如何使 shifter 成为 void 函数?
  • 因此,对于以当前方式编写函数的 5x5 板,您每次迭代都在堆栈上推送 25 个字符,但我不得不承认我不太确定这一点。您可以通过转到 void 函数并通过引用更改 a[][] 来避免这种情况并同时整理代码。无论您在例程中对 a[][] 采取的任何操作都已经反映在原始数组中,因为只有 a[][] 的内存位置被传递。
  • 哦,好吧。这是有道理的,但如果我将其设为 void 函数,那我将如何结束它?

标签: recursion stack-overflow


【解决方案1】:

检查递归调用。并给出终止条件。

if(terminate condition)
{
exit();
}
else
{
call shifter()
}

【讨论】:

  • 如果通过终止条件,你的意思是我得到的错误,就是这样。线程“main”java.lang.StackOverflowError 中的异常,然后它只是将 main 中的函数行重复 40 次。我不知道你检查递归调用是什么意思。
  • 对不起,我对 java 还是很陌生。我不确定如何使用终止条件。好吧,最初,我打算用直接的 for 循环来解决它,但是由于板的大小发生了变化,我不得不切换到递归。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-26
  • 1970-01-01
  • 2017-10-04
相关资源
最近更新 更多