堆栈在递归函数上溢出

时间:2017-05-20 21:12:04

标签: function recursion stack overflow

遇到了递归funktions的问题。我在java中创建了这个,这只是非常基本的,但由于堆栈溢出错误而无法正常工作。我的意思是这个函数的作用是打开funktion,就像给定数字和你在主要funktion中声明的数字之间的差异的大小一样,这对于堆栈来说应该不是什么问题,但是,doen'一直工作,或者这里的错误是什么......? 谢谢你的答案:)

public class Übung_Baeume {
    static int anzAufrufe=0;
    static int zahl=23;
    public static int zaehleAufrufe(int uebergabe)
    {
        anzAufrufe++;
        if (uebergabe==zahl){
            return anzAufrufe;
        }


        return zaehleAufrufe(uebergabe-1) + 
            zaehleAufrufe(uebergabe+1);

    }

    public static void main(String[] args) {
        System.out.println(zaehleAufrufe(40));
    }
}

2 个答案:

答案 0 :(得分:1)

这几乎总意味着没有什么能阻止递归越来越深入。无论达到目标是否达到某个水平,都没有条件停止。

在你的代码中,你从40开始,只有当你到达23时才会停止。但你的一个分支机构正在增加数字:

返回zaehleAufrufe(uebergabe-1)+ zaehleAufrufe(uebergabe + 1);

永远不会降到23岁。

欢迎使用堆栈溢出的StackOverflow:)

P.S。最好的办法是重新考虑你的algorythm。如果在确定的情况下你想要使用递归,但由于依赖于未知数据,它的分支是不可预测的,你可以设置一个限制值。这是一个脏黑客,但有些情况下它很有用。

  

可以说,使用此限制,您的代码将仍然失败    - 它会尝试将此函数调用多达2 ^ 33次=约80亿次,这足够大了:)

public class Übung_Baeume {
    static int anzAufrufe=0;
    static int zahl=23;
    static int max_level = 32;
    static bool fault = 0;
    public static int zaehleAufrufe(int uebergabe, int level)
    {
        if(level == max_level)
        {
            fault = 1;
            return 0;
        }
        anzAufrufe++;
        if (uebergabe==zahl){
            return anzAufrufe;
        }


        return zaehleAufrufe(uebergabe-1, level+1) + 
            zaehleAufrufe(uebergabe+1, level+1);

    }

    public static void main(String[] args) {

        int ret = zaehleAufrufe(40,0);
        if(fault == 0)
           System.out.println(ret);
        else
           System.out.println("Fault - recursion level limit reached!");
    }
}

答案 1 :(得分:1)

ubergabe如果不等于23将与ubergabe +1unbergabe - 1递归。现在每个人都会这样做,所以你可以试试这个:

zaehleAufrufe(40) ; ==>
zaehleAufrufe(39) + zaehleAufrufe(41) ; ==> neither of these are 23
zaehleAufrufe(38) + zaehleAufrufe(40) + zaehleAufrufe(40) + zaehleAufrufe(42)

注意最后一个..尽管其中一些最终会遇到一个基本情况,但你会发现你在3.扩展上有2 zaehleAufrufe(40)。这些中的每一个都像上面那样扩展为两个zaehleAufrufe(40),其中没有一个甚至可以达到基本情况。

对于递归工作,你需要变得更简单的问题,事实上你的问题变成了几个相同的数量,从而无限递归。

要打开一个函数多次,你只需要递归一次:

public static int zaehleAufrufe(int uebergabe)
{
    anzAufrufe++;
    if (uebergabe <= zahl) {
        return anzAufrufe;
    }
    return zaehleAufrufe(uebergabe-1);
}

zaehleAufrufe(40) ; ==>
zaehleAufrufe(39) ; ==>
...
zaehleAufrufe(23) ; ==> 18