实现真值表的一般模式

tbc*_*tbc 7 c++

实施真值表有一个很好的一般模式吗?

我正在重新编写一些遗留代码(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;
Run Code Online (Sandbox Code Playgroud)

基本上我想知道是否有更清晰,更可维护/可扩展的方式来设置它.

  • 如果添加了另一个输入怎么办?那么所需的if语句数量将是16,在我看来,使用当前模式进行管理会非常麻烦.
  • 如果几个输入组合应该映射到相同的输出怎么办?

*代码库是学术界使用的生态系统模型,因此维护和扩展相当于类似的东西,具体取决于编码器的角度.

CAF*_*FxX 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: // + + +
}
Run Code Online (Sandbox Code Playgroud)

  • 如果两个输入映射到相同的输出,您只需将这些情况放在一起并且直接通过.甚至比我的阵列建议更简单. (2认同)

Jon*_*ely 4

数组就是一个表。

布尔真值序列是二进制数。

数组按数字索引。

呜呜……

您可以为每个计算定义一个函数:

// - + + == 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);
}

// ...
Run Code Online (Sandbox Code Playgroud)

然后声明一个函数指针数组:

typedef double (*func_type)(double, double, double);
func_type funcs[8] = {
  f1, f2, // ...
};
Run Code Online (Sandbox Code Playgroud)

然后使用布尔条件作为二进制数字对数组进行索引:

func_type f = funcs[ (int(prevdst5 < 0.0)<<2) | (int(dst5 < 0.0)<<1) | int(nextdst5 > 0.0) ];
thawpct = f(prevdst5, dst5, nextdst5);
Run Code Online (Sandbox Code Playgroud)
  • 如果添加另一个输入怎么办?(那么测试的数量将是 16,在我看来,用当前的模式来管理会很麻烦)

如果需要不同的计算,则将数组的大小加倍并添加等f8f9但只需在数组索引中添加新测试一次:

func_type f = funcs[ (cond<<3) | (int(prevdst5 < 0.0)<<2) | (int(dst5 < 0.0)<<1) | int(nextdst5 > 0.0) ];
Run Code Online (Sandbox Code Playgroud)
  • 如果多个输入组合应映射到相同的输出怎么办?

将相同的函数指针存储在数组的多个元素处:

func_type funcs[8] = {
  f1, f2, f3, f1, f1, // ...
};
Run Code Online (Sandbox Code Playgroud)