分支取决于3个数字中的哪个最小

时间:2016-05-23 19:28:09

标签: c++ decision-tree goto

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

(编辑:很好我的意思是例如1)没有代码减少2)没有压缩性能3)而不强迫程序员做一些不必要的函数或临时变量)

考虑我想要执行3个不同代码块的情况,具体取决于abc中最小的数字。

代码如下所示:

    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
       }
    }

我不喜欢的是我必须复制// code block for "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网格(类似于Bresenham's line algorithm的3D格式,但起点是浮点(不对齐任何框的中心))

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

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
}

2 个答案:

答案 0 :(得分:6)

您可以使用std::min并使用带public function actionIndex() { $model = Cotizacion::find(); ->where(['created_at' BETWEEN time() - (30 * 60) AND time()]) ->all(); $this->layout = false; return $this->render('index', ['actionIndex' => $model]); } 的版本轻松解决此问题。您在三个变量上调用std::initializer_list以获得最小值,然后您有三个if语句来检查每个变量的返回值。

min

答案 1 :(得分:1)

顺便说一句,您不必嵌套条件:

if(a <= b && a <= c) { /* a is the lowest */ }
else if(b <= c) { /* b is the lowest */ }
else { /* c is the lowest */ }

请注意,C ++的运算符&&的语义是

if(a <= b && a <= c)

大致类似于

if(a <= b) if(a <= c)

(不同之处在于,后续的else子句(如果有的话)同时涵盖了if个。)在表达式cond1 && cond2中,如果cond1被证明是假的那么cond2永远不会被评估,至少它没有可观察到的副作用。

当然,我们可以通过非本地退出制作更具怪异性的东西,例如:

do {
    if(a <= b) {
        if(a <= c) {
            // a is the lowest
            break;
        }
    }
    else if(b <= c) {
        // b is the lowest
        break;
    }
    // c is the lowest
}
while(0);

但事实上,这个结构虽然高得多,但在逻辑上等同于上面的那三行(与Dieter的拟议编辑)。