实施真值表是否有良好的一般模式?
我正在重新处理一些遗留代码(C ++),并且意识到我正在使用的函数相当于一个包含3个二进制输入和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;
基本上我想知道是否有更清晰,更易维护/可扩展的方法来设置它。
*代码库是学术界使用的生态系统模型,因此根据编码器的观点,维护和扩展等同于类似事物。
答案 0 :(得分: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: // + + +
}
答案 1 :(得分: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,在我看来,使用当前模式进行管理会很麻烦)
如果需要进行不同的计算,您可以将数组的大小加倍并添加f8
,f9
等,但只需在数组索引中添加一次新测试:
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, // ...
};
答案 2 :(得分:0)
您可以将3(或n
)值的映射保存到需要执行的相应函数中。然后根据条件的true
/ false
状态循环此映射中的函数并执行该函数。
这样你就会得到一个3维的地图(所有维度的大小都是2)