2011-02-25 107 views
0

這個任務的目的是學習遞歸方法。對於這個特定的問題,我需要輸出list的值,每行一個。我需要完成的方法的骨架不能被改變,如下所示:Java Array遞歸

public void list (String[] list) { 

} 

的說明說,helper方法可以讓這個更容易編寫。這裏是我的幫手方法:

public void print(String[] list, int index) {  
     if (index < list.length) { 
      System.out.println(list[index]); 
      print(list, index+1); 
     } 
} 

我只想通過列表方法調用打印方法進行測試。我知道評分是通過一個腳本來完成的,所以我不能改變列表方法的返回類型或參數。請原諒我的格式錯誤,並提前感謝您的幫助!

+3

@Jeremiah - 通常當你看到這樣的無意義的東西時,它只是一個初學者造成的代碼格式錯誤。點擊編輯你自己,你可以看到他們出錯的地方並修復它。我已經這樣做了。通常很明顯,哪裏出錯,如果你修復它,它可以幫助每個人。 – 2011-02-25 01:53:00

+2

上課,注意,閱讀本書,提出問題,嘗試作業,然後來到這裏與你有什麼。 – 2011-02-25 02:03:02

+2

@問題在於人們已經將代碼給了這個人:D,現在他不會去下一堂課,不會讀這本書,也不會問問題,也不會嘗試作業:D – Serhiy 2011-02-25 02:14:50

回答

2

如果我這樣做,我會使用名稱爲print()或類似的助手方法。

在考慮程序的邏輯而言,想想你需要做什麼:

有一個輔助方法print()說:

  • 打印列表中的當前項目,上新行
  • 然後調用一個函數來打印在列表中的下一個及後續項目,每個項目上新的生產線

你覺得牛逼帽子的第二個功能可能是? 提示:它是遞歸的...

+0

Dan的另一個注意事項:請隨時對我們的回覆發表評論,以便我們可以在此進行對話以嘗試幫助您。我們不想給你作業的答案,但只要你努力增加你的理解力並進行對話,你就願意幫助你。 – Panky 2011-02-25 02:10:05

1

我不會給你直接的答案,因爲你不會從中學到任何東西。您可以創建變量來存儲當前深度。創建getter和setter助手方法來增加遞歸的深度。您的方法列表將使用相同的數組調用它自己,但只有在檢查深度不大於數組的大小後才能調用它自己。不要忘記在每次調用時增加遞歸的深度。

0

想一想這樣的遞歸解決方案:給定一堆東西(如列表)對這些事情之一(如列表的第一個元素)做一些事情,然後將剩下的東西傳遞給相同的東西解決方案,處理其中一件事情

提示:您需要考慮您的解決方案在沒有任何提供的情況下所做的工作。提示2:每次你遞歸的時候,不要「砍掉」數組,而只是注意你在數組中的位置。

0

讓我們從頭開始:

你可能已經知道,一個遞歸函數是一個調用自身。如果每次函數運行時都會調用它自己,那麼將會以無限循環結束。因此,始終確保您的功能知道何時停止調用本身也很重要。

我們該怎麼做?函數的主體在調用之間不會改變,因爲它是在編譯時設置的。然而,什麼會改變是該功能的輸入。每當你編寫一個遞歸函數時,你需要包含一些邏輯來避免在滿足某些條件時的遞歸調用。

在你的例子中,函數的輸入是一個字符串數組。知道何時停止進行遞歸調用的一種方法可能是每次將更小的數組傳遞給函數,並在您有一個空數組時停止。這對於像C這樣的語言來說會更好,在這種語言中數組是以指針的形式公開的,但是在Java中它會效率低下,因爲每次都必須創建一個新數組。

更好的解決方案是維護一個指向列表中當前位置的索引(這就是爲什麼你需要一個輔助函數 - 添加額外參數)。在每次調用時,只需在當前索引處打印字符串並增加索引即可。當索引不再位於數組中時,就完成了!

如果你真的想很好地理解遞歸,我推薦學習一種函數式語言,比如Lisp,Haskell或ML。函數式語言避免了可變狀態(改變變量的值),因此它們不會像循環一樣使用(因爲需要在每次迭代時更新循環計數器)。所以他們用遞歸來實現循環!例如,在Java中,我們可能有:

for (int i = 0; i < 10; i++) { 
    System.out.println("Loop index: " + i); 
} 

而在OCaml中我們會寫:

let times = 10 in 
let rec loop count = 
    if count = times then 
    printf "Loop index: %d" count ; 
    loop (count + 1) 
;; 

這裏最重要的區別是,而不是改變計數的值(實際上不可能給定上述OCaml代碼),我們每次都會將新值傳遞給loop函數。

0

當你這樣做遞歸,它有時是有幫助的寫出來,你會如何使用循環執行相同的任務:

public void list(String[] list) { 
    for(int index = 0; index < list.length; index++) { 
     System.out.println(list[index]); 
    } 
} 

現在,假設我們想更接近一個遞歸解決方案。第一步可能是擺脫for循環的內部部分:

public void list(String[] list) { 
    for(int index = 0; index < list.length; index++) { 
     list(list, index); 
    } 
} 

public void list(String[] list, int index) { 
    System.out.println(list[index]); 
} 

好了,現在我們是真正貼近遞歸解決方案。我們只需要完成循環處理的最後兩項任務,遞增index並檢查是否爲index < list.length。這些看起來像是他們可能是減排步驟和基本案例的理想人選。