2017-01-24 132 views
2

我是新來的java,我正在研究一些關於遞歸的文章,當我偶然發現這個我不明白的小程序時。遞歸調用結果

static void print(int i) { 

    if (i > 1) { 
     System.out.print("Y"); 
     print(i-1); 
    } 

    for (int t = 0; t < i ; t++) 
     System.out.print(i); // i not t 
    } 

當我做print(4)結果是YYY1223334444但爲什麼不是YYY1?我沒有那部分。

+2

您是否試過在調試器中逐步調試? (提示:在if塊已經完成後,你認爲會發生什麼?) –

+1

Oeh多數民衆贊成在一個好的,我會立即嘗試,謝謝 –

回答

8

部分的答案是最好的方法:推出代碼並查看實際調用方法的順序。重要的是知道遞歸print(i-1)呼叫是阻止。它會一直等到它的調用已經返回,然後繼續下一個語句,這是for循環。這意味着,當你到達i參數爲1的呼叫時,你可以調用4個深度:print(4) - > print(3) - > print(2) - > print(1)。這就是爲什麼人們會說「調用堆棧」,以及爲什麼在輸出異常時得到堆棧跟蹤。哦,以及爲什麼你得到stackoverflow錯誤,這個網站被調用後,如果你的調用堆棧變得如此之深(例如,遞歸沒有結束條件),它超過了一定的值。

雖然傑拉爾德鍵入他的答案,我做了一個視覺表示,可能會幫助你更好地展現。彩色塊是方法調用,嵌套顯示它們在調用堆棧中如何彼此疊放,以及程序語句流程的箭頭。 recursive program flow & call stack

+0

不能要求比這更正確的答案!謝謝。 –

+0

你用什麼來創建這個奇特的圖? – Gala

+0

@Gala我使用了draw.io,您可以在瀏覽器中使用它並且是免費的。這是由jGraph。就圖表軟件而言,這似乎是對我的努力做出最小的阻力:D –

5

讓我們推出ifs,遞歸和循環。系統的功能如下:

print(i=4) { 
    System.out.print("Y")   -> Y 
    print(i=3) { 
    System.out.print("Y")  -> YY 
    print(i=2){ 
     System.out.print("Y")  -> YYY 
     print(i=1){ 
     //skip if and print 1x i=1 
     System.out.print(1)  -> YYY1 
     } 
     //print 2x i=2 
     System.out.print(2)  -> YYY12 
     System.out.print(2)  -> YYY122 
    } 
    //print 3x i=3 
    System.out.print(3)  -> YYY1223 
    System.out.print(3)  -> YYY12233 
    System.out.print(3)  -> YYY122333 
    } 
    //print 4x i=4 
    System.out.print(4)  -> YYY1223334 
    System.out.print(4)  -> YYY12233344 
    System.out.print(4)  -> YYY122333444 
    System.out.print(4)  -> YYY1223334444 
} 

代碼deos不會在if之後返回,而是執行for循環。

如果你是新來的Java,讓自己熟悉的調試器,它允許一步一步的執行和價值內省,是由傑拉爾德·穆克提供所有的Java IDE

+0

謝謝,但一個小問題。在'if'後面的代碼執行'for'loop,但不是'我'在那一刻1,它是怎麼變成2的? –

+0

@YoussefSakuragi通過返回調用它的方法,其中'i'是2.遞歸的一個基本概念是多個調用堆疊起來,直到您回到它們。 – pjs

+2

'i-1'不會更改'i'的值,而是會創建一個新值,並將其傳遞給下一個調用。但是一旦該方法返回,原來的'i'的值再次有效, –