你如何缩短这一点,以便action1和action2只在代码中显示一次?

时间:2009-02-23 16:34:55

标签: c++ c

if (x() > 10)
{
    if (y > 5)
        action1(p1, p2, p3, p4);
    else
        action2(p1, p2);
}
else
{
    if (z > 2)
        action1(p1, p2, p3, p4);
    else
        action2(p1, p2);
}        

我在我的实际项目中,action1和action2实际上是2-3行代码,而那些被调用的函数总共需要6-8个参数,因此将它们作为单个函数编写似乎不正确。

更新:我忘记提及这一点,现在我看到许多答案都不起作用。 x()是昂贵的操作并且有副作用,因此不应该调用两次。

11 个答案:

答案 0 :(得分:15)

if (should_do_action1(x(), y, z))
    action1(p1, p2, p3, p4);
else
    action2(p1, p2);

答案 1 :(得分:12)

if ((x > 10 && y > 5) || (x <= 10 && z > 2))
   action1(p1, p2, p3, p4);
else
   action2(p1, p2);

答案 2 :(得分:10)

你总是可以这样做:

if ((x > 10) ? (y >5) : (z > 2)) action1
else action2

为了完整起见,任何if p then q else r语句都可以逻辑表示为(!p && r) || q。因此,我们可以将原始陈述表达为:

a = x > 10
b = y > 5
c = z > 2
(!a && (!c && action2) || ((!b && action2) || action1))

您可以扩展为:

(!a && !c && action2) || 
(!a &&  c && action1) || 
( a && !b && action2) || 
( a &&  b && action1)

如果你将action1收集到一边,你会得到:

( a &&  b && action1) ||
(!a &&  c && action1) || 

( a && !b && action2) || 
(!a && !c && action2)

它真的扩展到:

( a &&  b &&  c && action1) ||
( a &&  b && !c && action1) ||
(!a &&  b &&  c && action1) || 
(!a && !b &&  c && action1) || 

( a && !b &&  c && action2) || 
( a && !b && !c && action2) || 
(!a &&  b && !c && action2) ||
(!a && !b && !c && action2)

从中我们可以看到我们可以将其简化为:

( a &&  b &&  c && action1) ||
( a &&  b && !c && action1) ||
(!a &&  b &&  c && action1) || 
(!a && !b &&  c && action1) || 
action2

由于导致action2的所有路径都是导致action1的任何路径的否定,我们可以进一步将其减少为:

( a &&  b && action1) ||
(!a &&  c && action1) || 
action2

本身可以简化为:

((( a &&  b &&) || (!a &&  c)) && action1) || 
action2

然后可以写成:

if ((a && b) || (!a && c)) action1
else action2

哪个成了:     if((x> 10&amp;&amp; y&gt; 5)||(!(x&gt; 10)&amp;&amp; z&gt; 2))action1     否则action2

无论如何,这是我们得到的。

答案 3 :(得分:8)

bool condition_satisfied = (x() > 10 ? y > 5 : z > 2);
if (condition_satisfied)
    action1(p1, p2, p3, p4);
else
    action2(p1, p2);

或者,Roger Lipscombe answered

答案 4 :(得分:5)

我喜欢原始的,冗长的版本。但前提是它遵循代码所描述的系统内部逻辑。否则,也许应该是“对立面”:

int xRes = x();
if (y > 5) 
{
    if (xRes > 10)
        action1(p1, p2, p3, p4);
    else
        action2(p1, p2);
}
else if (z > 2)
{
    if (xRes > 10)
        action1(p1, p2, p3, p4);
    else
        action2(p1, p2);
}
else
{
    action2(p1, p2);
}

无论如何,如果你对最短的解决方案感兴趣,可以这样:

((x>10 && y>5) || (x<=10 && z>2)) ? action1(p1, p2, p3, p4) : action2(p1, p2);

答案 5 :(得分:3)

我想不出更清楚或更简单地表达它的方法。它可以缩短,但它会使它更难理解。

答案 6 :(得分:2)

//Yeah, I know this is wrong. Explanation below.
if ((x() > 10 && y > 5) || (x() <= 10 && z > 2))
    action1(p1, p2, p3, p4);
else
    action2(p1, p2);

[edit]更改了代码,因为我的条件逻辑错了。

但就个人而言,为了便于阅读,我更喜欢你更详细的版本。

[edit2]正如评论所注意到的那样,我似乎很难做到这一点。我会注意到这是因为我会这样做的方式几乎就是这个问题最初的陈述。我更喜欢布尔运算符字符串的详细程度,因为在我看来,它使操作的逻辑更容易可视化。

答案 7 :(得分:2)

因为x()很昂贵,所以缓存结果。然后结合action1的前提条件:

int x = x();
if ((x>10 && y>5) || (x<=10 && z>2))
{
    action1(p1,p2,p3,p4);
}
else 
{
    action2(p1,p2);
}

答案 8 :(得分:1)

如果你想用1 if语句来做,我认为它会是:

if ((x > 10) && (y > 5)) || ((x <= 10) && (z > 2))
    action1(p1, p2, p3, p4);
else
    action2(p1, p2);

答案 9 :(得分:1)

你知道,在看到这里的一些回复之后,我不得不说你的原始版本更具可读性,当然更容易理解。我唯一的改变就是在 else 行添加一些注释,说明else的情况是x&lt; = 10。

我不认为缩短代码在任何情况下都不再是一个问题。我知道如果你是一个老式的程序员,你希望尽可能简洁,但是我们都有100 + Gb驱动器和编译器,无论如何都会崩溃任何这些替代品,所以为什么不选择可读性?我2美分:))

答案 10 :(得分:1)

var valX= x();
if ((valX > 10  && y>5) || (valX<=10 && z>2))
{

        action1(p1, p2, p3, p4);
}
else
{  
        action2(p1, p2);  
}