2017-05-20 142 views
-2

得到了遞歸函數的問題。我在java中創建了這個,這只是非常基本的,但由於Stack overflow錯誤而不起作用。我的意思是這個函數的作用就是打開funktion,就像給定數字和你在主函數中聲明的數字之間的差異一樣多,這對堆棧來說應該不是什麼問題,但是, t一直工作,或者這裏的錯誤是什麼......? 謝謝你的答案提前:)遞歸函數堆棧溢出

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)); 
    } 
} 

回答

1

這幾乎總是意味着沒有任何東西可以從去越陷越深停止遞歸。達到一定程度的目標是否達到目標是沒有條件的。

在你的代碼從40開始,只有當你到23,但是你的一個分支將停止增加數:

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

,絕不會下降到23

歡迎與堆棧溢出:)

附:到計算器最好的辦法是重新考慮你的算法。如果你是確定你想要使用遞歸,但由於取決於未知數據,它的分支是不可預知的,所以你可以設置一個限制級別的值。這是一個骯髒的黑客,但有些情況下,它是有用的。

這是importaint說,與此限制您的代碼將仍然無法 - 它會嘗試調用這個函數高達2^33倍=約8十億,這是足夠大:)

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

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