2017-01-04 101 views
2

我一直認爲讓你的代碼不易遵循而又可以避免的事情被認爲是不好的做法。遞歸似乎是這些事情之一(更不用說它可能會導致堆棧溢出等問題),所以當我們在編程課程中必須認真對待他們時,我感到有點驚訝(因爲它偶爾會導致更短的結果碼)。在我看來,這兩位教授之間也存在分歧......遞歸是一個不好的習慣嗎?

人們已經問過這種語言的具體情況(比如Python,其評論將其與goto聲明相比較),主要針對某個問題,但我對一般感興趣:

遞歸在現代編程中是否被認爲是不好的實踐?我什麼時候應該避免它,並且在什麼情況下不能?


相關的問題,我發現:

Is recursion a feature in and of itself?(不討論究竟是好還是壞)
Is recursion ever faster than looping?(答案描述了遞歸可能導致功能性語言的改進,但價格昂貴的其他人) ,還有其他問題討論性能

+2

如果這更適合理論計算機科學,隨時遷移。 – Neinstein

+0

對於某些語言來說,並不是真正的意見。當選擇的工具鏈或VM可能不支持TCO時,簡單的遞歸函數應該由其他控制結構來實現。對於不能處於尾部位置的調用,這是一個可預測深度的問題,如'O(log n)'空間或可預測的小數據結構,以便可以使用簡潔的遞歸函數,然後選擇優先級,而不是使用實用程序回溯的解決方案堆棧堆棧不會增長系統堆棧,這會降低可讀性但更強大。 – Sylwester

回答

3

遞歸編程並不是一個壞習慣。它是工具箱中的工具,就像任何工具一樣,當它是唯一使用的工具時,就會發生不好的事情。或者當它在適當的環境下使用時。

什麼時候使用遞歸?你有一個樹數據集,你需要執行相同的邏輯,這是很好的。例如:你有一個字符串元素樹列表,你想計算所有字符串的總長度,向下一個分支。你需要定義一個方法來計算列表元素的長度,然後看看元素是否有兄弟,以及它是否調用方法,傳遞兄弟 - 並重新開始這個過程。

最常見的陷阱是堆棧溢出。當清單如此之大時,不能一次處理完畢。所以你會實施檢查以確保這種情況永遠不會發生。比如把鏈表分解成可管理的部分和你的函數,利用一個靜態變量來跟蹤你遍歷的層次數 - 一旦超過這個數就進行保存。

當數據集不是樹型數據集時,應避免使用。我唯一能想到的是,你實際上無法避免使用遞歸是在不支持循環的編程語言(Haskell)中。

相關問題