解决方案很明显,但这是关于好的解决方案的问题。
(编辑:很好我的意思是例如1)没有代码减少2)没有压缩性能3)而不强迫程序员做一些不必要的函数或临时变量)
考虑我想要执行3个不同代码块的情况,具体取决于a
,b
,c
中最小的数字。
代码如下所示:
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着色器,物理模拟)。任何会增加一些不必要的计算开销的东西都是不可能的。
其他问题/意见
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
}
答案 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的拟议编辑)。