2017-07-13 87 views
7

我學習遞歸和下面是一個例子,我追蹤通過更好地理解它遞歸 - 爲什麼用return語句

public static void main(String []args) { 
    new TestRecursion().strRecur("abc"); 
} 

public void strRecur(String s) { 
    if(s.length() < 6) { 
     System.out.println(s); 
     strRecur(s+"*"); 
    } 
} 

下面是我到目前爲止的理解。 - 在第一次調用strRecur("abc")時,該方法被添加到執行堆棧中。由於使用參數「abc *」進行遞歸調用,它會在暫停之前打印「abc」。

  • 與 「ABC *」 的第二個電話,推方法strRecur(abc*)到堆棧和打印 「ABC *」 到控制檯。

  • 第三次調用「abc **」,將方法strRecur(abc**)推送到堆棧並將「abc **」打印到控制檯。

  • 第四次調用「abc ***」,將方法strRecur(abc***)推送到堆棧。由於滿足基本條件,該方法完成(不打印任何內容)並彈出堆棧。

  • 第三次調用「abc **」完成並彈出。由於沒有待處理的代碼執行任何操作。

  • 第二次調用「abc *」完成並彈出。由於沒有待處理的代碼執行任何操作。

  • 帶「abc」的初始調用完成並彈出。由於沒有待處理的代碼執行任何操作。以下控制檯

Stack

雕塑 -

abc 
abc* 
abc** 

我想我明白這裏發生了什麼。現在,我想嘗試一下這段代碼的細微變化。與其說strRecur(s+"*")的,我想這樣做return strRecur(s+"*")

public class TestRecursion { 

    public static void main(String []args) { 
     new TestRecursion().strRecur("abc"); 
    } 

    public String strRecur(String s) { 
     if(s.length() < 6) { 
      System.out.println(s); 
      return strRecur(s+"*"); 
     } 
     return "Outside If"; 
    } 
} 

我的期望是,一旦strRecur(abc***)彈出,它的輸出(ABC ***)將返回到堆棧中的下一個strRecur(),所以我會請參閱控制檯中打印的abc ****。其他遞歸調用也是如此。

但是,這種情況下的輸出與沒有返回語句時的輸出完全相同。我的理解(當然這是不正確)從遞歸階乘的實現,我們這樣做

return n * fact(n-1); 

這裏fact(n-1)與的n返回值解決,一旦在棧上以前的方法完成莖。爲什麼在這個例子中沒有以相同的方式返回?

+0

[可運行示例](https://ideone.com/GTCArI),以防萬一任何人想要提琴。 – Michael

+0

只是一個簡短的建議:我發現,當試圖理解遞歸時,如果您打印出每個電話的詳細信息,它會有所幫助。例如用'System.err.println(「> strRecur s =」+ s)''來啓動你的遞歸方法;'並且在返回之前,你需要'System.err.println(「 biziclop

回答

8

這兩種方法的輸出是由遞歸方法中的println語句產生的,這就是爲什麼它在兩種方法中都是相同的。

第二種方法返回的值不會打印到任何位置,這就是您看不到它的原因。

如果您打印第二種方法的結果,您會看到它是"Outside If",因爲這是最後一次遞歸調用的輸出,然後由所有其他方法調用返回。

如果你想在輸出爲abc***,你應該

return s; 

,而不是

return "Outside If"; 

完整的代碼是:

public static void main(String[] args) { 
    System.out.println(new TestRecursion().strRecur("abc")); 
} 

public String strRecur(String s) { 
    if(s.length() < 6) { 
     return strRecur(s+"*"); 
    } 
    return s; 
} 
+0

此外,我不知道OP的要求是什麼,您可能需要將6更改爲5.他的第一個示例僅獲得'abc **' – Michael

0

這裏是如何使它返回值而不是打印它:

public static void main(String[] args) { 
    String result = StrRecur("abc"); 
    System.out.print(result); 
} 

public static String StrRecur(String s) { 
    if(s.length() < 6) { 
     return s + "\n" + StrRecur(s+"*"); 
    } 
    return ""; 
} 

這也是一樣的,但副作用只發生在main

相關問題