if statement - 进口食品关税 - 如果条件A匹配,则需要匹配条件B以执行动作C.




纺织品进口关税 (8)

使用标志也可以解决这个问题

int flag = 1; 
if ( condition A ) {
    flag = 2;
    if( condition B ) {
        flag = 3;
    }
}
if(flag != 2) { 
    do action C 
}

我的问题是:

if (/* condition A */)
{
    if(/* condition B */)
      {
         /* do action C */
      }
    else
      /* ... */
}
else
{
   /* do action C */
}

是否可以只编写一次C代码而不是两次?

如何简化?


呃,这也让我感到高兴,但正如 Code-Apprentice指出的那样, 我们保证需要 do action C 或运行嵌套的 else 块,因此代码可以简化为:

if (not condition A or condition B) {
    do action C
} else {
    ...
}

这就是我们如何击中3个案例:

  1. 嵌套的 do action C 在你的问题的逻辑要求 condition Acondition Btrue - 在这个逻辑中,如果我们到达 if 语句中的 第二个 术语,那么我们知道 condition Atrue 因此我们需要评估是 condition Btrue
  2. 你问题逻辑中嵌套的 else -block要求 condition Atruecondition Bfalse - 我们可以在这个逻辑中达到 else -block的唯一方法是 condition Atruecondition Bfalse
  3. 你问题逻辑中的外部 else -block要求 condition Afalse - 在这个逻辑中如果 condition A 为假,我们也会 do action C

Code-Apprentice的道具让我在这里理顺。 我建议接受 他的答案 ,因为他没有编辑就正确地提出 了答案 :/


在逻辑概念中,您可以按如下方式解决此问题:

f = ab +!a
f =?

作为经证实的问题,这导致 f = !a + b 。 有一些方法可以证明问题,如真值表, 卡诺图 等。

所以在基于C语言中你可以使用如下:

if(!a || b)
{
   // Do action C
}

PS: 卡诺图 也用于更复杂的一系列条件。 这是一种简化布尔代数表达式的方法。


尽管已经有了很好的答案,但我认为这种方法对于那些刚接触布尔代数然后评估真值表的人来说可能更直观。

您要做的第一件事就是查看您要在哪些条件下执行C.这是 (a & b) 。 也是当 !a 所以你有 (a & b) | !a (a & b) | !a

如果你想最小化你可以继续下去。 就像在“普通”算术中一样,你可以相乘。

(a & b) | !a = (a | !a) & (b | !a) (a & b) | !a = (a | !a) & (b | !a) 。 a | !a总是如此,所以你可以把它划掉,这样就可以得到最小化的结果: b | !a b | !a 。 如果顺序有所不同,因为你只想检查b!a是否为真(例如,当a是空指针检查而b是对指针的操作,如@LordFarquaad在他的评论中指出),你可能会想要切换两个。

另一种情况(/ * ... * /)将在c未执行时始终执行,因此我们可以将其放在else的情况下。

另外值得一提的是,将动作c放入方法可能有意义。

这给我们留下了以下代码:

if (!A || B)
{
    doActionC()  // execute method which does action C
}
else
{
   /* ... */ // what ever happens here, you might want to put it into a method, too.
}

通过这种方式,您还可以使用更多操作数来最小化术语,这些操作数很快会因真值表而变得难看 另一个好方法是卡诺图。 但我现在不会深入研究这个问题。


您有两种选择:

  1. 编写执行“动作C”的功能。

  2. 重新排列逻辑,以便您没有这么多嵌套的if语句。 问问自己什么条件导致“行动C”发生。 它看起来像是在“条件B”为真或“条件A”为假时发生。 我们可以把它写成“NOT A OR B”。 将其转换为C代码,我们得到

    if (!A || B) {
        action C
    } else {
        ...
    }
    

为了更多地了解这些表达式,我建议谷歌搜索“布尔代数”,“谓词逻辑”和“谓词演算”。 这些都是深刻的数学主题。 您不需要全部学习,只需要了解基础知识。

您还应该了解“短路评估”。 因此,表达式的顺序对于精确复制原始逻辑非常重要。 而 B || !A B || !A 在逻辑上是等价的,使用它,因为当 B 为真时,无论 A 的值如何,条件都将执行“动作C”。


我会将C提取到一个方法,然后在所有情况下尽快退出该函数。 如果可能的话,在最后应该使用单个事物的 else 条款几乎总是被反转。 这是一个循序渐进的例子:

提取C:

if (A) {
   if (B)
      C();
   else
      D();
} else
   C();

首先反转 if 要摆脱第一个:

if (!A) {
   C();
   return;
}

if (B)
   C();
else
   D();

摆脱第二个:

if (!A) {
   C();
   return;
}

if (B) {
   C();
   return;
} 

D();

然后您可以注意到这两个案例具有相同的主体并且可以组合:

if (!A || B) {
   C();
   return;
}

D();

可选的改进方法是:

  • 取决于上下文,但如果 !A || B !A || B 令人困惑,将其提取到一个或多个变量来解释意图

  • C()D() 都是非特殊情况应该是最后一个,所以如果 D() 是异常,那么最后一次反转 if


这些问题的第一步始终是制作逻辑表。

A | B | Result
-------------------
T | T | do action C
T | F | ...
F | T | do action C
F | F | do action C

一旦你制作了表格,解决方案就很明确了。

if (A && !B) {
  ...
}
else {
  do action C
}

请注意,这种逻辑虽然较短,但对于未来的程序员来说可能难以维护。


问题陈述:

如果条件A匹配,则需要匹配条件B以执行动作C.

描述 implication A 暗示 B ,一个等同于 !A || B 的逻辑命题 !A || B (如其他答案中所述):

bool implies(bool p, bool q) { return !p || q; }

if (implies(/* condition A */,
            /* condition B */))
{
    /* do action C */
}




boolean-logic