代码之家  ›  专栏  ›  技术社区  ›  starf15h

如果条件A匹配,则需要匹配条件B才能执行操作C

  •  150
  • starf15h  · 技术社区  · 8 年前

    我的问题是:

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

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

    12 回复  |  直到 8 年前
        1
  •  401
  •   QuestionC    8 年前

    在这类问题中,你的第一步总是要做一个逻辑表。

    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
    }
    

        2
  •  65
  •   Code-Apprentice    8 年前

    您有两种选择:

    1. 重新安排逻辑,这样就不会有那么多嵌套的if语句。问问自己是什么条件导致了“行动C”的发生。在我看来,当“条件B”为真或“条件A”为假时,就会发生这种情况。我们可以写为“不是A或B”。将其转换为C代码,我们得到

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

    为了进一步了解这类表达式,我建议在谷歌上搜索“布尔代数”、“谓词逻辑”和“谓词演算”。这些都是深入的数学主题。你不需要全部学习,只需要基本知识。

    您还应该了解“短路评估”。因此,表达式的顺序对于精确复制原始逻辑非常重要。虽然 B || !A 逻辑上是等价的,使用此作为条件将在以下情况下执行“动作C” B A

        3
  •  15
  •   Michael come lately PhiLho    4 年前

    if ((A && B) || (!A)) // or simplified to (!A || B) as suggested in comments
    {
        do C
    }
    

    否则,将“C”的代码放在一个单独的函数中,并调用它:

    DoActionC()
    {
        ....
        // code for Action C
    }
    if (condition A)
    {
        if(condition B)
        {
            DoActionC(); // call the function
        }
        else
        ...
    }
    else
    {
       DoActionC(); // call the function
    }
    
        4
  •  14
  •   Aaron M. Eshbach    8 年前

    在具有模式匹配的语言中,可以更直接地反映问题C答案中的真值表来表达解决方案。

    match (a,b) with
    | (true,false) -> ...
    | _ -> action c
    

    如果您不熟悉语法,每个模式都由一个|表示,后跟要匹配的值(a,b),下划线用作通配符,表示“任何其他值”。因为我们想做动作c以外的事情的唯一情况是当a为真,b为假时,我们显式地将这些值声明为第一个模式(真,假),然后在这种情况下做任何应该做的事情。在所有其他情况下,我们采用“通配符”模式并执行操作c。

        5
  •  10
  •   jamesdlin    8 年前

    问题陈述:

    描写 implication : A. 暗示 !A || B (如其他答复中所述):

    bool implies(bool p, bool q) { return !p || q; }
    
    if (implies(/* condition A */,
                /* condition B */))
    {
        /* do action C */
    }
    
        6
  •  6
  •   Jonathan Mee    8 年前

    呃,这也把我绊倒了,但是 pointed out by Code-Apprentice do action C else 块,因此代码可以简化为:

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

    这就是我们处理这3个案例的方式:

    1. 执行操作C 在你的问题逻辑中需要 condition A condition B true nd公司 if -声明那么我们就知道了 条件A 条件B 真的
    2. 嵌套的 -阻止问题的逻辑 条件A 成为 成为 false 其他的 -此逻辑中的块将是如果 真的 条件B
    3. 其他的 -阻止问题的逻辑 --在此逻辑中,如果 条件A

    代码学徒的道具,让我在这里直截了当。我建议接受 his answer

        7
  •  6
  •   Siyavash Hamdi    8 年前

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

    f=a.b+!一
    f=?

    f = !a + b . Karnaugh Map 等等

    因此,在基于C的语言中,您可以使用以下内容:

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

    卡诺图 这是一种简化布尔代数表达式的方法。

        8
  •  6
  •   deetz    8 年前

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

    (a & b) 。同时 !a . 所以你有 (a & b) | !a

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

    (a & b) | !a = (a | !a) & (b | !a) . a |!a总是真的,所以你可以把它划掉,这样你就得到了最小化的结果: b | !a 如果订单有差异,因为您只想在以下情况下检查b!a为true(例如,当!a为空指针检查,b为指针上的操作,如@LordFarquaad在其评论中指出的),您可能需要切换这两个选项。

    另一种情况(/*…*/)is将始终在不执行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.
    }
    

    通过这种方式,还可以使用更多的操作数最小化项,这在真值表中很快就会变得难看。另一个好方法是卡诺图。但我现在不会深入讨论这个问题。

        9
  •  4
  •   anatolyg    8 年前

    bool do_action_C;
    
    // Determine whether we need to do action C or just do the "..." action
    // If condition A is matched, condition B needs to be matched in order to do action C
    if (/* condition A */)
    {
        if(/* condition B */)
          do_action_C = true; // have to do action C because blah
        else
          do_action_C = false; // no need to do action C because blarg
    }
    else
    {
      do_action_C = true; // A is false, so obviously have to do action C
    }
    
    if (do_action_C)
      {
         DoActionC(); // call the function
      }
    else
      {
      ...
      }
    
        10
  •  3
  •   Ali Faris    8 年前
    if((A && B ) || !A)
    {
      //do C
    }
    else if(!B)
    {
      //...
    }
    
        11
  •  2
  •   Dave Cousineau    8 年前

    我会将C提取到一个方法中,然后在所有情况下尽快退出该函数。 else 如果可能的话,结尾只有一件事的子句几乎总是应该颠倒过来。下面是一个逐步的示例:

    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

    • 以其中之一为准 C() D() D() 如果 最后一次

        12
  •  2
  •   Sede    8 年前

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