在递归方法中解决stackoverflowException

时间:2011-01-11 17:36:02

标签: java recursion stack-overflow

我已经为我的作业写了一个方法来计算递归的整数数组的所有排列。 (我正在尝试实现回溯算法)。但它会导致StackOverflowException计算超过7个数字的前置数。我不知道如何解决这个问题。如果我使用itration,它仍会实现回溯吗?

代码:

solve(0, arr, currentS);
//****************

private static void solve(int i, ArrayList<Integer> arr, int[] currentS) {
    if (i == arr.size()) {
        for (int j : currentS) {
            System.out.print(j + ",");
        }

        System.out.println();

        currentS[i-1] = 0;
        solve(i - 2, arr, currentS);

    } else {
        int x = nextValue(i, currentS, arr);
        if (x != -1&&travers.isCompatible(arr, currentS.clone())) {
            currentS[i] = x;
            solve(i + 1, arr, currentS);
        }
        else if((i != 0))
        {
            currentS[i] = 0;
            solve(i - 1, arr, currentS);
        }
    }
    return;
}

nextValue()是在树的节点的子节点中检查没有重复的方法,从根到每次离开都没有重复

异常:

Exception in thread "main" java.lang.StackOverflowError
    at java.util.ArrayList.get(Unknown Source) ....

2 个答案:

答案 0 :(得分:2)

不要让你失望,但我对这个问题的解决方案有14行代码。也许你应该重新思考你的方法。

提示:您实际上不需要单独的列表来保存当前的排列,您可以直接置换(和取消)数组。这意味着您不需要任何代码来检测列表中的重复项。

但你的问题可能更基本。维基百科writes

  

递归函数定义   一个或多个基本案例,意思是   输入功能的输入   琐碎地产生一个结果(没有   反复出现),以及一个或多个递归   案例,意思是对其的输入   程序重复(调用自身)。对于   例如,阶乘函数可以   由等式递归地定义   0! = 1,并且,对于所有n&gt; 0,n! = n(n -   1)!这两个方程本身都没有   构成一个完整的定义;该   第一个是基本情况,第二个是   是递归的情况。的工作   递归案例可以看作是   将复杂的输入分解成   更简单的。在一个设计合理的   递归函数,每个   递归调用,输入问题必须   以这样的方式简化   最终基本情况必须如此   达到

(强调我的)。我没有看到任何保证i == arr.length将会到达的企图。有时候我会在递归时变小,有时会变大,很有可能它只会在没有达到基本情况的情况下振荡。换句话说,您的程序永远不会终止,但由于每个递归步骤都需要额外的内存,因此您的堆栈空间不足。

答案 1 :(得分:0)

假设您的算法是正确的并且对7个数字正常工作......

那么您可能需要的是更多的堆栈空间。这可以在Java命令行上通过为1兆位堆栈大小添加“-Xss1024k”来完成。您可以增加更多空间。这样做可能会给你你需要的东西。

但是,你必须明白,总是存在堆栈空间的上限,并且递归算法可能会遇到上限。您可能最好使用不使用调用堆栈来存储您需要执行的工作的其他算法。有时候最好使用堆空间来代替类似Queue或Stack类的实例来保存你的状态。