明白這一點的方式是通過其手動步驟,使用筆和紙。 我不能強烈推薦你實際上對這件事物理上用真正的紙片,直到你明白髮生了什麼。
用一張紙記錄輸出。
每次調用printName()
時都使用一張新的單獨紙張。
從main()
開始。當您看到printName("Brian", 0)
時,這是啓動新紙張的信號。在工作表頂部,寫入輸入:name - "Brian", index = 0
。
現在你在printName()
,所以一步一步地通過它。 0
小於"Brian".length() - 1
,這樣你就可以跳到else
塊:
System.out.println(name.charAt(index));
- 這麼寫的"Brian".charAt(0)
結果在你的輸出表:B
。
printName(name, index + 1) -- since you're seeing
printName()again, take another sheet of paper, write the inputs
名稱= 「布賴恩」,索引= 1`在頂部,和地方此上與前一薄片的頂部。
繼續以這種方式工作,您將繼續添加到您的紙張堆。這與Java維護的執行堆棧直接類似;這是您在堆棧跟蹤中看到的相同堆棧。
最終你會達到index = "Brian".length() -1
的點,所以你回來。當您看到return
時,請取下正在使用的紙張,將其擰緊並將其投入垃圾箱。運行時已完成此方法的調用。繼續下面的表格,從中斷。你現在在第二個System.out.println(name.charAt(index));
。所以把這個字符寫在輸出表上。
當你完成後,你會發現你在輸出表上寫了「BriannairB」,你應該對遞歸有更好的理解。
每張紙都代表堆棧幀。請記住:
- 在執行期間的給定時刻,只有最上面的堆棧幀在執行過程中「可見」。
- 局部變量和參數存儲在堆棧幀中。在執行的某個時刻,當前堆棧幀中
index
的值將爲3
。這對下面堆棧幀中index
的值沒有影響 - 這是一個完全獨立的存儲器,當3
幀結束並彈出堆棧時仍將爲2
。
一旦你得到的這個竅門,但是,你可以看看它在更多的「聲明」的水平。是做什麼的?
它打印「B」,然後printName("Brian", 1
),然後「B」。
我覺得這個實現稍微容易理解:
void printName(String s) {
if(s.length() > 0) {
System.out.println(s.charAt(0));
printName(s.substring(1));
System.out.println(s.charAt(0));
}
}
所以,printName("Brian")
寫道B
然後printName("rian")
然後B
。
或者從最深去堆棧會:
printName("")
沒有寫。
因此printName("n")
寫入n
然後printName("")
然後n
- 這是nn
。
看看第二個'System.out.println' - 它在遞歸達到結束後被調用。 –
除了Jaroslaw的評論,請注意'index + 1'不會改變'index'的值。因此,在下一行中,打印相同的字符。 –
謝謝。我明白第二個System.out.println是什麼導致它,但它是如何索引正在減少導致字母倒退?我必須錯過簡單的東西。 –