2012-06-18 71 views
7

實現真值表是否有一個很好的一般模式?實現真值表的一般模式

我正在重新編寫一些遺留代碼(C++),並意識到我正在使用的函數相當於一個帶有3個二進制輸入和8個可能輸出的真值表。這裏是2的8個測試和相應的輸出的一個示例:

// - + + 
if ((prevdst5 < 0.0) && (dst5 > 0.0) && (nextdst5 > 0.0)){ 
    thawpct = (dst5/(dst5 - prevdst5)); 
} 

// - - + 
if ((prevdst5 < 0.0) && (dst5 < 0.0) && (nextdst5 > 0.0)){ 
    thawpct = (nextdst5/(nextdst5 - dst5)); 
} 

// other cases... 

return thawpct; 

基本上我想知道是否有一個更清潔,更易於維護/可擴展的方式*設置此。

  • 如果添加了另一個輸入會怎麼樣?那麼if語句所需的數量應該是16,在我看來,使用當前模式管理起來太麻煩了。
  • 如果幾個輸入組合應該映射到相同的輸出怎麼辦?

*代碼庫是學術界使用的生態系統模型,因此根據編碼人員的觀點,維護和擴展相當於類似的東西。

+0

你確定嗎? dst5 = 0.0是否在其他地方,或超出範圍? –

+0

不知道我明白嗎?實際上在函數頂部有一個測試: if(dst5 == 0.0)dst5 = 0.001; 我認爲這是一個錯誤(比較浮點數是否相等) – tbc

+0

(太遲以至於無法修改以前的評論)解決方法:不知道我明白嗎?實際上有這樣一個測試:if(dst5 == 0.0)dst5 = 0.001;對於函數頂部的每個輸入。我實際上認爲這是一個錯誤(比較浮點數是否相等),但至少需要注意每個輸入爲0的可能性。 – tbc

回答

4

數組是一張表。

布爾真值的序列是一個二進制數。

數組按數字索引。

SOOOOO .....

你可以定義一個函數爲每一個計算:

// - + + == 0 1 1 == 3 
inline double f3(double prev, double curr, double next) 
{ 
    return curr/(curr - prev); 
} 

// - - + == 0 0 1 == 1 
inline double f1(double prev, double curr, double next) 
{ 
    return next/(next - curr); 
} 

// ... 

然後聲明函數指針的數組:

typedef double (*func_type)(double, double, double); 
func_type funcs[8] = { 
    f1, f2, // ... 
}; 

然後索引到陣列使用布爾條件作爲二進制數字:

func_type f = funcs[ (int(prevdst5 < 0.0)<<2) | (int(dst5 < 0.0)<<1) | int(nextdst5 > 0.0) ]; 
thawpct = f(prevdst5, dst5, nextdst5); 
  • 如果添加了另一個輸入會怎麼樣? (然後測試的數目將是16,這在我視圖會很麻煩與當前模式來管理)

您加倍數組的大小並添加f8f9等如果不同的計算是需要的,但你只添加新的測試一次,在數組索引:

func_type f = funcs[ (cond<<3) | (int(prevdst5 < 0.0)<<2) | (int(dst5 < 0.0)<<1) | int(nextdst5 > 0.0) ]; 
  • 如果幾個輸入連擊應該映射到什麼相同的輸出?

存儲在陣列的幾個要素相同功能的指針:

func_type funcs[8] = { 
    f1, f2, f3, f1, f1, // ... 
}; 
0

你可以保持的3(或n)值的映射到需要執行適當的功能。然後根據條件的狀態true/false循環此映射中的函數並執行該操作。

這樣,你就必須(在所有dimentions有大小2)的3維地圖

8
int condition = (prev >= 0 ? (1<<0) : 0) + 
       (cur >= 0 ? (1<<1) : 0) + 
       (next >= 0 ? (1<<2) : 0); 

switch (condition) { 
    case 0: // - - - 
    case 1: // + - - 
    case 2: // - + - 
    case 3: // + + - 
    case 4: // - - + 
    case 5: // + - + 
    case 6: // - + + 
    case 7: // + + + 
} 
+2

如果兩個輸入映射到相同的輸出,則只需將這些情況彼此相鄰並進行下穿。甚至比我的數組建議更簡單。 –

+0

我以前見過條件運算符,但我被第二個操作數中的「1 << 0」弄糊塗了? Johathan Wakely在他的回答中使用了類似的東西... – tbc

+0

@myself - 發現它移動運算符:http://stackoverflow.com/questions/141525/absolute-beginners-guide-to-bit-shifting – tbc