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

Mil*_*kov 1 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);
}        
Run Code Online (Sandbox Code Playgroud)

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

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

Rog*_*mbe 15

if (should_do_action1(x(), y, z))
    action1(p1, p2, p3, p4);
else
    action2(p1, p2);
Run Code Online (Sandbox Code Playgroud)


Col*_*tin 12

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


MSN*_*MSN 10

你可以随时做:

if ((x > 10) ? (y >5) : (z > 2)) action1
else action2
Run Code Online (Sandbox Code Playgroud)

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

a = x > 10
b = y > 5
c = z > 2
(!a && (!c && action2) || ((!b && action2) || action1))
Run Code Online (Sandbox Code Playgroud)

你可以扩展为:

(!a && !c && action2) || 
(!a &&  c && action1) || 
( a && !b && action2) || 
( a &&  b && action1)
Run Code Online (Sandbox Code Playgroud)

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

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

( a && !b && action2) || 
(!a && !c && action2)
Run Code Online (Sandbox Code Playgroud)

它真的扩展到:

( 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)
Run Code Online (Sandbox Code Playgroud)

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

( a &&  b &&  c && action1) ||
( a &&  b && !c && action1) ||
(!a &&  b &&  c && action1) || 
(!a && !b &&  c && action1) || 
action2
Run Code Online (Sandbox Code Playgroud)

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

( a &&  b && action1) ||
(!a &&  c && action1) || 
action2
Run Code Online (Sandbox Code Playgroud)

哪个本身可以简化为:

((( a &&  b &&) || (!a &&  c)) && action1) || 
action2
Run Code Online (Sandbox Code Playgroud)

然后可以写成:

if ((a && b) || (!a && c)) action1
else action2
Run Code Online (Sandbox Code Playgroud)

成为:if((x> 10 && y> 5)||(!(x> 10)&& z> 2))action1 else action2

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


Dan*_*nas 8

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

或者,或者Roger Lipscombe 回答的问题.


Igo*_*Oks 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);
}
Run Code Online (Sandbox Code Playgroud)

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

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