2011-03-15 68 views
1

我在我的智慧結束......我理解遞歸的更簡單的例子,但當我變得棘手時,我沒有線索。這是一個例子。如果有人能說出它的作用,我會很高興。什麼是編譯器做...遞歸 - 它做什麼

public static char mystery(String s, int n, int m) 
{ 
if (n==1) return s.charAt(m); 

char first = mystery(s, n/2, m*2); 
char second = mystery(s, n/2, m*2 +1); 

System.out.print(first + " " + second + " "); 

return first; 
} 

什麼時候該方法被調用打印: 謎( 「fredpass」,5,1)

答案是passps

我不沒有CLUE他們是如何到達那裏的......

如果有人能幫助我處理這件事情,我會非常感激。在互聯網上的其他地方,他們只解釋階乘 - 簡單的例子。不知道會發生什麼,如果你把它叫做char first = mystery (blah);兩次,然後再次char second = mystery (blah);

+1

那麼,這種方法的意圖是什麼呢?但它是如何工作的就像其他任何形式的遞歸一樣。 – 2011-03-15 12:58:13

+6

這條線是否正確? 'char second = mystery(s,n/s,m * 2 +1);'當試圖用一個字符串除n時,'n/s'部分是否會通過編譯錯誤? – justkt 2011-03-15 12:59:01

+0

這些數字對我來說沒有意義。爲什麼你有'n/s'而不是'n/2'? – 2011-03-15 13:00:44

回答

5

用手就跟蹤調用:

mystery(5, 1) 
    first = mystery(2, 2) 
     first = mystery(1, 4) = 'p' 
     second = mystery(1, 5) = 'a' 
    second = mystery(2, 3) 
     ... 

等。給自己足夠的紙張來繪製調用堆棧的完整圖片,函數調用的狀態以及局部變量。例如,在我的圖片中最裏面的呼叫打印「p a」後,它返回'p',所以我會在mystery(2, 2)後面寫下該字母。

5

因此,你已經知道recursion的例子以及它如何使用。

也許你缺少的是爲什麼遞歸工作。爲了理解這個,你需要知道當一個方法被調用時會發生什麼。熟悉call stack

就邏輯上發生的事情而言,您應該考慮按順序在代碼中「行走」。當您遞歸調用一個方法時,它將簡單地返回結果並繼續執行,就像在任何其他過程代碼中一樣。然而,每個方法調用都有自己的scope of variables,它們只在遞歸的特定調用中有效。

1

按照@ jleedev的回答所述,手「執行」是一項有用的練習,尤其是如果您以前從未做過。

另一種方法是在Java調試器的控制下運行代碼,並在檢查調用堆棧/局部變量時單步執行。這不太容易出錯,但如果你做得太快,你可能會錯過實際發生的重要細節。

不要太擔心它對你來說是個謎,mystery函數實際上是做什麼的。它顯然被設計爲難以理解。 (除了神祕之外,我看不出有任何意義......)除了神祕之外,大多數遞歸函數都會做一些有用的事情,並且會更容易理解......帶着經驗...

0

對於每一次遞歸都有兩件事要考慮:

  1. 每個遞歸方法都應該有一個基本情況。
  2. 每個遞歸都應該朝着這個基本情況前進