【发布时间】:2016-09-20 19:22:39
【问题描述】:
解决方案很明显,但这是关于不错的解决方案的问题。
(编辑:nice 我的意思是例如 1)没有代码冗余 2)不影响性能 3)不强迫程序员制作一些不必要的函数或临时变量)
考虑一下我想根据a、b、c 中哪个数字最小来执行 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
}
}
我不喜欢的是我必须复制// 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 着色器、物理模拟)。任何会增加一些不必要的计算开销的东西都是没有问题的。
其他问题/cmets
- 这是我觉得Structured programming 束缚我的双手的几个例子之一,这只是
jump指令可能做的事情的一部分。您是否知道使用goto而不是标准控制结构的算法会更简单和清晰的其他示例? - 您能想象更复杂的分支,需要多次复制某些代码块吗?
编辑:用例
我认为一些混乱是由于我没有指定我想使用它的上下文。这是光线追踪常规 triclinic 3D 网格的算法的一部分(类似于 3D 中的 Bresenham's line algorithm,但起点是浮动的(不与任何框的中心对齐))
但是请不要把注意力集中在算法本身上,它也可能是错误的,我正在调试它。
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你在找什么吗? -
不,不是。 (顺便说一句。我正在查看以前提出的问题......主题最重要的是stackoverflow.com/questions/11833327/…)
-
你的问题的问题是 nice 并没有真正为每个人定义相同的。
-
@Drop > 这是真的,但代码重复不喜欢任何人(我猜)
-
你觉得这个“好”吗:
return (a < b) ? ( (a < c) ? a : b ) : c;?
标签: c++ decision-tree goto