堆栈溢出的原因是什么?

时间:2011-10-24 04:57:53

标签: java android recursion stack-overflow

我正在为Java应用程序编写一个函数,该应用程序使用StringBuilder生成字符串的所有排列。

每当运行该函数时,程序立即终止,并且DDMS(Dalvic虚拟机调试工具)在我的函数中声明堆栈溢出。

private void reorder(String reorder_this, StringBuilder in_this){

    for(int i = 0; i < reorder_this.length(); i++)
    {
        if(i == reorder_this.length())
        {
            in_this.append(System.getProperty("line.separator"));
        }
        else
        {
            in_this.append(reorder_this.charAt(i));
            reorder(reorder_this.substring(0, i) + reorder_this.substring(i), in_this);
        }
    }
}

你可以看到我已经对这个问题采取了递归方法,我相信最终会填充字符串生成器,其中包含输入字符串的所有可能排列,每个排列后跟换行字符。

有没有人知道可能导致堆栈溢出的原因?

3 个答案:

答案 0 :(得分:5)

简而言之,除非字符串的长度为0,否则您的函数无法终止。

您的方法首先将i设置为0并测试i是否小于第一个参数的长度。如果是(除了空字符串之外的所有情况),你立即递归,因为你不能严格地小于长度等于长度。在递归调用中,传入一个完全相同长度的字符串(实际上,与Thilo指出的完全相同的字符串)。这表明该算法的第二个问题:递归算法应该对每个递归调用的“较小”参数进行操作。

在这里获得StackOverflowException不会花费很长时间。每个递归调用都会推送一个新的堆栈帧。

答案 1 :(得分:2)

Java中任何堆栈溢出的原因都是无限递归。

private void reorder(String reorder_this, StringBuilder in_this){
    for(int i = 0; i < reorder_this.length(); i++)
    {
        if(i == reorder_this.length())
        {

通过构造无法访问此块。所以你的终止条件永远不会得到满足。

答案 2 :(得分:0)

我认为问题在于这一行:

reorder(reorder_this.substring(0, i) + reorder_this.substring(i), in_this);

reorder_this.substring(0, i) + reorder_this.substring(i)将生成相当于reorder-this

的字符串