简化逻辑表达式

时间:2011-09-29 03:33:44

标签: c logic conditional

注意:这是 NOT 作业。

我想提出正确的方法来设计正确的算法来处理这个简单的问题。

我有一个状态(可用正整数表示)随时间变化。我有另一个值,它是一个恒定的特定状态(用一个特定的正整数表示),第一个状态可能等于。

最好这样说明:

// this is C pseudocode

int things_happen(int *value) {
  ... // value possibly gets changed!
}

const int y = VALUE_Y_CONST; 
int x = y; // to simplify things we assume x starts out equal to y

while (things_happen(&x)) {
  // I am now interested in changes to x with respect to y. 
  if (/* expression of interest */) { 
    x_is_changed(); // I want to know whenever x is no longer y
  }
  if (/* another expression of interest */) {
    x_is_back(); // and I want to know whenever x becomes equal to y again
  }
}

如何确定何时应拨打x_is_changed()x_is_back()

在尝试编程时,我已经多次遇到过这种情况。每次,我提出的解决方案看起来都非常复杂,并且经常会出现错误。

到目前为止,我的解决方案要求我创建第三个变量,我用它来缓存while循环底部的x值。它允许我知道我的x 更改了哪个值。有了这些知识,我就会使用看似完全过多的条件语句:

int x_cache = y;
while(things_happen(&x)) {
  if (x_cache != x) {
    if (x == y && x_cache != y)
      x_is_back();
    else if (x != y && x_cache == y)
      x_is_changed();
    x_cache = x;
  }
}

到目前为止,这是我做到最简洁的方式。代码很难遵循。我想知道的是,是不是有更好的算法来解决这个问题?我应该采取什么样的方法?我以为我可以画一个真值表,但我只能用真值来做。我在3个变量之间做了相同的事情并得到了这个表:

x_cache == x | x_cache == y | x == y  ||  x_is_changed | x_is_back
                                      || 
    T                T          T     ||       F            F 
    T                T          F     ||       F            F
    T                F          T     ||       F            F
    T                F          F     ||       F            F
    F                T          T     ||       F            F
    F                T          F     ||       T            F
    F                F          T     ||       F            T
    F                F          F     ||       F            F

这似乎是我从逻辑课中记得的唯一一件事。 我注意到由于传递性,行2,3和5是不可能的。所以,如果我只考虑值之间的相等性检查,我肯定似乎限制自己。

我是否应该继续提出命题变量,并寻找减少操作总数的特定组合?有一个更简单的方法吗?提出最有效的任意条件算法的一般问题显然是NP完全的(关于变量的数量)。

进一步盯着那张桌子,越过第2,3和5行,我看到条件x_cache != x将消除前4行,这很好,然后我留下3种可能性。我此时可以看到x_cache == y等于x_is_changedx == y也等于x_is_back

这意味着我可以从上到下进行简化:

...
  if (x_cache != x) {
    if (x == y)
      x_is_back();
    else if (x_cache == y)
      x_is_changed();
    x_cache = x;
  }
...

我仍觉得这不是最佳选择。我不认为存在其他可以帮助解决这个问题的关系运算符。它现在可能是最佳的,现在我考虑一下。

我直觉第2,3和5行是不可能的。没有这些知识,我无法将问题减少到如此少的操作。是否有一些数学/逻辑概念允许我系统地执行这种“修剪”?

1 个答案:

答案 0 :(得分:3)

我认为最简单的形式是:

int x_cache = 1;
while(things_happen(&x)) {
  if (x_cache != (x==y)) {
    if (x == y)
      x_is_back();
    else
      x_is_changed();
    x_cache = (x==y);
  }
}

另一种选择是

for (;;) {
  while (things_happen(&x) && x==y) { }
  if (x==y) break;
  x_is_changed();
  while (things_happen(&x) && x!=y) { }
  if (x!=y) break;
  x_is_back();
}