我正在解决Project Euler上的问题9 .在我的解决方案中,我使用"goto"语句来打破两个for循环.问题如下:
毕达哥拉斯三元组是一组三个自然数,abc,为此,
a ^ 2 + b ^ 2 = c ^ 2
例如,3 ^ 2 + 4 ^ 2 = 9 + 16 = 25 = 52.
恰好存在一个毕达哥拉斯三元组,其中a + b + c = 1000.找到产品abc.
我的解决方案是在c ++中:
int a,b,c; const int sum = 1000; int result = -1; for (a = 1; a由于"goto"语句在c ++程序员中不是很受欢迎,我想知道,如果这可以被认为是合理使用"goto".或者如果对于不需要"goto"的问题有更好的解决方案.我并不是指一种只避免"转到"的解决方案,而是以改进算法的方式避免"转向".
1> Alex Martell..:
return
是一个"结构化"goto
,许多程序员发现更容易接受!所以:static int findit(int sum, int* pa, int* pb, int* pc) { for (int a = 1; a
+1:如果它足够复杂以考虑goto,它足够复杂,可以封装在一个函数中并避免使用goto.
@onebyone,当然,还有各种各样的原教旨主义者;-),但是"单身回归"在任何我愿意为之努力的地方都非常薄弱:与恐惧症(一种良好的良性疾病)不同程序员,由于过去遭遇意大利面条代码而感到伤痕累累),单一性肠炎是一种恶性(尽管很少见)综合症,需要大刀阔斧的治疗... ;-)
这种方法的唯一缺点是,与"从不使用GOTO !!!"的战斗.人群,你直接与"功能必须只有一次回归!!!"战斗 人群.所以采用这种方法因为你喜欢它,觉得"findit"是一个很好的抽象,并愿意为它辩护,很好.仅仅为了避免转到这种方法是徒劳的.
是的.不要让循环复杂化.只是出去了.完美解决方案 但你可以通过引用传递a,b,c.然后你不需要乱用指针.
@Martin,我更喜欢这样的想法,无论我是用C语言还是C++编程,调用f(a)都不会改变a - 如果我们"有时"让它发生,那么心灵的平静就会消失.并且检查(例如)pa是否为空是像检查(例如)a*a + b*b没有溢出那样超级 - 只是调用者必须遵守的合同的一部分.最后,引用也可能错误地为null(接收int&a,传递*p,其中int*p为0,只是在接收函数中打印&a,你会看到0)......! - ).
优秀.因此,剩下的就是对死亡和血腥到第七代的战斗,关于应该如何处理多个返回值.我说你需要"课堂PythagoreanTriple:private boost :: tuple";-)
2> StackedCrook..:在我看来,
goto
在这样的情况下使用是很好的.顺便说一下,对goto的居高临下的讲道通常来自那些只是鹦鹉学舌的人,他们听到别人说或在某处读到的东西.
@Casebash:好的.但这与答案或问题有何关系?
3> Matthew Vine..:看到关于突破2个循环的这个问题.提供的答案比使用goto要好得多.
提供的最佳答案是将第二个循环放入函数中,并从第一个循环中调用该函数.
从mquander的回复复制的代码
public bool CheckWhatever(int whateverIndex) { for(int j = 0; j < height; j++) { if(whatever[whateverIndex][j]) return false; } return true; } public void DoubleLoop() { for(int i = 0; i < width; i++) { if(!CheckWhatever(i)) break; } }虽然我觉得在这种情况下使用goto并不像杀小猫那么糟糕.但它很接近.
我们怎么都洗脑了?:)这个代码的结果结构比使用goto更复杂(由于DoubleLoop中额外的'if-statement').拆分代码也可能会减少编译器可以进行的优化集 - 例如,"CheckWhatever"本地的变量可能已被优化为在封闭循环之外.