c++ - 根据 3 个数字中最小的那个进行分支

标签 c++ decision-tree goto

解决方案很明显,但这是关于好的解决方案的问题。

(编辑:nice 我的意思是,例如 1)没有代码冗余 2)没有牺牲性能 3)没有强制程序员创建一些不必要的函数或临时变量)

假设我想根据 abc 中哪个数字最小来执行 3 个不同的代码块。

代码看起来像这样:

    if( a < b ){
       if( a < c ){  
           // code block for "a is minimum" case
       }else{        
           // code block for "c is minimum" case
       }
    }else{
       if( b < c ){
           // code block for "b is minimum" case
       }else{    
           // code block for "c is minimum" case
       }
    }

我不喜欢的是我必须复制 //"c is minimum"case 代码块两次。

有几种解决方案。例如。我可以将"c is minimum" 的代码块放入内联函数 中。但我不喜欢它(阅读起来似乎不太清楚)。

老派的解决方案是使用 goto,例如:

    if( a < b ){
       if( a < c ){  
           // code for "a is minimum" case
           goto BRANCHE_END;
       }
    }else{
       if( b < c ){ 
           // code for "b is minimum" case
           goto BRANCHE_END;
       }
    }
   // code for "c is minimum" case
   BRANCHE_END:

但是人们不喜欢看到 goto(有充分的理由)。另一方面,在这种特殊情况下,它甚至具有很好的可读性。

如果代码块是独立的函数,它可以这样写

 void myBranching( double a, double b, double c ){
    if( a < b ){
       if( a < c ){  
           // code for "a is minimum" case
           return;
       }
    }else{
       if( b < c ){ 
           // code for "b is minimum" case
           return;
       }
    }
   // code for "c is minimum" case
    return;
 }

(实际上和那个goto几乎一样)但是在很多情况下,类似的代码块必须是更复杂算法的一部分,并且将它放在函数中是不方便的。封装在函数中需要传递许多在内部和外部都使用的变量(例如,请参见下面的用例)。

在 C/C++ 中是否有任何控制结构可以优雅地解决这个问题。

注意:考虑性能关键代码。 (例如光线追踪器、GLSL 着色器、物理模拟)。任何会增加一些不必要的计算开销的事情都是不可能的。


其他问题/评论

  • 这是我觉得 Structured programming 的几个例子之一绑住我的手,这只是 jump 指令可能做的事情的子集。您是否知道使用 goto 而不是标准控制结构的算法会更加简单明了的其他示例?
  • 您能想象更复杂的分支,需要多次复制某些代码块吗?

编辑:用例

我认为有些困惑是由于我没有指定要在其中使用它的上下文。这是光线追踪规则算法的一部分 triclinic 3D 网格(类似于 3D 中的 Bresenham's line algorithm,但起点是 float 的(未与任何框的中心对齐))

但是请不要关注算法本身,它也可能是错误的,我正在调试它。

double pa,pb,pc,invPa,invPb,invPc,mda,mdb,mdc,tmax,t;
int ia,ib,ic; 
// for shortness I don't show initialization of these variables
while( t<tmax ){
    double tma = mda * invPa;
    double tmb = mdb * invPb;
    double tmc = mdc * invPc;
    if( tma < tmb ){
       if( tma < tmc ){  // a min
            t   += tma;
            mda  = 1;
            mdb -= pb*tma;
            mdc -= pc*tma;
            ia++;
       }else{            // c min
            t   += tmc;
            mda -= pa*tmc;
            mdb -= pb*tmc;
            mdc  = 1;
            ic++;
       }
    }else{
       if( tmb < tmc ){  // b min
            t   += tmb;
            mda -= pa*tmb;
            mdb  = 1;
            mdc -= pc*tmb;
            ib++;
       }else{            // c min
            t   += tmc;
            mda -= pa*tmc;
            mdb -= pb*tmc;
            mdc  = 1;
            ic++;
       }
    }
    // do something with ia,ib,ic,mda,mdb,mdc
}

最佳答案

您可以使用 std::min 轻松解决此问题并使用带有 std::initializer_list 的版本。您对三个变量调用 min 以获得最小值,然后您有三个 if 语句来检查每个变量的返回值。

void foo(int a, int b, int c)
{
    int min = std::min({a, b, c});
    if (min == a)
    {
        // a case
    }
    else if (min == b)
    {
        // b case
    }
    else
    {
        // c case
    }
}

关于c++ - 根据 3 个数字中最小的那个进行分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37399010/

相关文章:

java - Java中有goto语句吗?

c++ - 如何解决错误 : Cannot convert from 'OSamp::Weapon' to 'OSamp::Weapon' in C++ CLR

c++ - minGW(使用 g++ 4.7.1)不编译简单的 C++11 代码(在 WinVista 下)

machine-learning - 使用自动学习重构决策树

python - 使用 scikit-learn 时,如何找到我的树 split 的属性?

c# - C#中的goto语句

c++ - 继承类中的比较运算符

C++测量执行时间

r - 如何根据 R 中的决策树模型测试数据?

c - gets() 函数从第二次开始被跳过