2009-09-17 70 views
2

是的,我知道措辭很難理解,但是這是讓我感到很困擾的東西。在最近的一個項目中,我有一個遞歸的函數,並且有很多條件會導致它停止遞歸(目前爲三)。哪種情況是可選的? (I.E.最佳性能或最簡單的維護)。有條件地執行一個函數的最好方法是什麼?

1)條件回報:

void myRecursingFunction (int i, int j){ 
    if (conditionThatWouldStopRecursing) return; 
    if (anotherConditionThatWouldStopRecursing) return; 
    if (thirdConditionThatWouldStopRecursing) return; 

    doSomeCodeHere(); 
    myRecursingFunction(i + 1, j); 
    myRecursingFunction(i, j + 1); 
} 

2)包裹在整個事件中的if語句

void myRecursingFunction (int i, int j){ 
    if (
     !conditionThatWouldStopRecursing && 
     !anotherConditionThatWouldStopRecursing && 
     !thirdConditionThatWouldStopRecursing 
    ){ 
     doSomeCodeHere(); 
     myRecursingFunction(i + 1, j); 
     myRecursingFunction(i, j + 1); 
    } 
} 

3)你就錯了小白,任何理智的算法將永遠使用遞歸。

+0

第一個例子等同於在第二個例子中使用||,所以二者不會相同。 – 2009-09-17 20:56:29

+0

@Lasse - 咦?如果這讓你感到困惑,我也會否定條件。 – MiffTheFox 2009-09-17 21:01:12

回答

6

這兩種方法都應該在幕後產生相同的IL代碼,因爲它們是等效的布爾表達式。請注意,每個終止條件將按您編寫的順序進行評估(因爲編譯器無法確定哪一個最可能),因此您需要首先使用最常見的終止條件。

儘管structured programming指出第二種方法更好,但個人而言,我更喜歡將代碼返回條件作爲遞歸方法頂部的單獨塊。我發現更容易閱讀和遵循(雖然我不是在方法體的隨機區域中返回的粉絲)。

3

我會選擇第一個解決方案,因爲這使得它完全清楚停止遞歸的條件是什麼。 它更可讀,更可維護imho。

1

我喜歡的變體1更好...

這是很容易閱讀,然後變種2.在這裏,你必須瞭解3個否定,並與連鎖它們組合在一起。我知道它不是「硬」,但它需要更長的時間,然後觀察變種1

3

如果是需要快速的東西,我建議儘可能快地打最常見的情況(即將基本情況放在最後,因爲您只會打一次)。還可以考慮在遞歸子句之前放置一個基本的case-1(即,在再次調用該函數之前執行測試,而不是在進入後續調用時檢查它),如果這會有所作爲。

而且,儘管如此,除非是問題,否則不要優化。我會先澄清一下。

+0

我懷疑這是否有所作爲。在遞歸之前,您仍然必須測試基本情況,而不管回報的順序如何。 – recursive 2009-09-17 21:54:17

+0

如果它是 - 或者是的。我在考慮具有多於一個流的函數(例如,switch/case語句或嵌套的if語句)。但是對於這個問題,是的,你是對的。 – Joe 2009-09-17 22:27:42

0

我的投票也是選項#1。我看起來更清楚。

相關問題