我正在解决 Project Euler 上的问题9。在我的解决方案中,我使用<!>“goto <!>”;声明打破两个for循环。问题如下:

  

毕达哥拉斯三重态是一组三个自然数,一个b c,为此,

     

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;

由于<!>“goto <!>”;语句在c ++程序员中不是很受欢迎,我想知道,如果这可以被认为是合理使用<!>“goto <!>”。或者,对于不需要<!>“goto <!>”的问题,有更好的解决方案。我不是指一个只避免<!>“goto <!>”的解决方案,但它避免了<!>“goto <!>”;以改进算法的方式。

有帮助吗?

解决方案

return是<!> quot;结构<!> 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;
}

其他提示

在我看来,在这种情况下使用goto是可以的。

Btw,对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;
    }
}

虽然我觉得在这种情况下使用goto并不像杀死小猫那么糟糕。但它很接近。

我想不出更好的选择。但是,一种不使用goto的替代方法是修改第一个for - 循环:

for (a = 1; a<sum && result == -1; a++){

然后break退出第二个-1 - 循环。假设结果在第二个<=> - 循环被<=>断开后,结果将永远不会<=>。

您可以在顶部声明bool found = false,然后将&& !found添加到for循环条件中(在a < sumb < sum之后),然后将找到的当前goto设置为true。然后使输出条件为found为true。

我刚刚在<!>上找到了这个;相关的<!>侧边栏。一个有趣的线程,但特别是,是我的问题的答案。

int a,b,c,sum = 1000;
for (a = 1; a<sum; ++a)
 for (b = 1; b<sum; ++b){
  c = sum-a-b;
  if (a*a+b*b == c*c) sum = -a*b*c;
 }
printf("a: %d\n",a-1);
printf("b: %d\n",b-1);
printf("c: %d\n",c);
printf("Result: %d\n",-sum);

同时优化结果..:P

无论如何我喜欢搞砸了!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top