2012-03-22 70 views
3

雖然與NLP打我已經遇到了一點小問題:嵌套開關替代

switch(var1) 
{ 
case Variant1_1: 
    if(cond1) 
    { 
     if(cond2) 
     { 
      if(cond3) 
      { 
       switch(var2) 
       { 
       case Variant2_1: 
        return someExpression; 
       // another five-six cases 
       default: 
        return; 
       } 
      } 
      else // cond3 
      { 
       switch(var2) 
       { 
       case Variant2_1: 
        return someExpression; 
       // another five-six cases 
       default: 
        return; 
       } 
      } 
     } 
     else // cond2 
     { 
      if(cond3) 
      { 
       switch(var2) 
       { 
       case Variant2_1: 
        return someExpression; 
       // another five-six cases 
       default: 
        return; 
       } 
      } 
      else // cond3 
      { 
       switch(var2) 
       { 
       case Variant2_1: 
        return someExpression; 
       // another five-six cases 
       default: 
        return; 
       } 
      } 
     } 
    } 
    else // cond1 
    { 
     // same thing 

    } 
    break; 
case Variant1_2: 
    // same gigantic tree 
    break; 
case Variant1_3: 
    // here too 
    break; 
default: 
    return; 
} 

是這樣的「計算樹」有什麼辦法?唯一出現在我腦海中的是一些帶有函數指針葉子和很多小函數的樹形容器。

+0

這段代碼應該重構,不僅在這個函數中,而且還有其他函數。有時候,重構只有一個函數沒有多大幫助,或者並不那麼容易,但是考慮整個項目的設計(或者至少其他相關函數)會有很大幫助。然後,重構很容易,您可以期望更好的整體設計。 – Nawaz 2012-03-22 15:31:12

+0

對於每個條件組合,表達式是否真的獨立?在我的經驗中很少見。通常情況下,可以考慮一些共同點來減少個案的嘗試次數。 – 2012-03-22 15:31:33

+0

考慮到這是NLP ..我想還會有更多的:-) – MadRunner 2012-03-22 15:55:38

回答

4

(在面頰上的舌頭)每當您在C++程序中遇到switch聲明時,您都知道您錯過了繼承機會。我知道重構多個並行開關的兩種方式是(1)構建函數指針的多維數組,以及(2)使用visitor pattern的變體。

+0

O'kay,我想我會停下來多陣列,謝謝! 但是,對於沒有經驗的程序員,您能否在這種情況下澄清您對「訪客模式」使用的看法? – MadRunner 2012-03-22 16:03:57

0

你所描述的是編譯器會從你的代碼中得到什麼:)所以你基本上提出了一個嵌套的編程語言,它帶來了格林斯潘的定律:「任何足夠複雜的C或Fortran程序都包含一個廣告特別的,非正式的,錯誤的,慢一半的Common Lisp。「

有些方法可以更好地編寫此代碼來表達您的條件。當你有很多嵌套的if() { if() { if() } } }時,通常只需編寫if (!condition) break;或其他轉義方法,簡化代碼。並不總是,但很多時候。

1

一個很好的解決方法是使用矩陣。

這將很好地工作,如果你知道所有的條件無論如何都會被評估。

製作一個多維陣列,將所述真 - 假值映射到處理功能。

Arrayswitch[var1][cond1][cond2][cond3][var2](); 
1

我開始尋找一種數據驅動的方法,當代碼開始看起來像這樣。它可以像表格一樣簡單,也可以像您建議的那樣使用帶有函數指針的樹。

如果這是某種類型的手動解析器,您可能需要查看一些關於解析的參考資料,以瞭解如何使用語法定義進行解析(通過解釋需求語法或使用使用語法作爲輸入的代碼生成工具)。

我經常用手卷的遞歸下降解析器。通常,我創建一個保存狀態的類,公開一個「Parse」函數,並將每個規則實現爲一個私有成員函數。這些成員函數很小且明確命名,所以代碼變得很可讀。爲它編寫測試也很容易。

+0

這不僅僅是這種情況,這個函數處理flex,但感謝您的想法!猜猜我會盡快使用它:-) – MadRunner 2012-03-22 16:15:09