我正在解决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<sum; a++){
for (b = 1; b < sum; b++){
c = sum-a-b;
if (a*a+b*b == c*c){
result = a*b*c;
goto found;
}
}
}
found:
std::cout << "a:" << a << std::endl;
std::cout << "b:" << b << std::endl;
std::cout << "c:" << c << std::endl;
std::cout <<"Result:" << result << std::endl;
Run Code Online (Sandbox Code Playgroud)
由于"goto"语句在c ++程序员中不是很受欢迎,我想知道,如果这可以被认为是合理使用"goto".或者如果对于不需要"goto"的问题有更好的解决方案.我并不是指一种只避免"转到"的解决方案,而是以改进算法的方式避免"转向".
Ale*_*lli 46
return是一个"结构化" goto,许多程序员发现更容易接受!所以:
static int findit(int sum, int* pa, int* pb, int* pc)
{
for (int a = 1; a<sum; a++) {
for (int b = 1; b < sum; b++) {
int c = sum-a-b;
if (a*a+b*b == c*c) {
*pa = a; *pb = b; *pc = c;
return a*b*c;
}
}
return -1;
}
int main() {
int a, b, c;
const int sum = 1000;
int result = findit(sum, &a, &b, &c);
if (result == -1) {
std::cout << "No result!" << std::endl;
return 1;
}
std::cout << "a:" << a << std::endl;
std::cout << "b:" << b << std::endl;
std::cout << "c:" << c << std::endl;
std::cout <<"Result:" << result << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Sta*_*ked 18
在我看来,goto在这样的情况下使用是很好的.
顺便说一下,对goto的居高临下的讲道通常来自那些只是鹦鹉学舌的人,他们听到别人说或在某处读到的东西.
看到关于突破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;
}
}
Run Code Online (Sandbox Code Playgroud)
虽然我觉得在这种情况下使用goto并不像杀小猫那么糟糕.但它很接近.