使用 goto 是打破两个循环的合法方法吗?

发布于 2024-07-25 16:23:37 字数 1001 浏览 10 评论 0 原文

我正在解决 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;

由于“goto”语句在c++程序员中不太流行,我想知道这是否可以被认为是“goto”的合理使用。 或者是否有更好的解决方案来解决不需要“goto”的问题。 我的意思并不是指仅仅避免“goto”的解决方案,而是以改进算法的方式避免“goto”的解决方案。

I am solving problem 9 on the Project Euler. In my solution I use a "goto" statement to break out of two for loops. The Problem is the following:

A Pythagorean triplet is a set of three natural numbers, a b c, for which,

a^2 + b^2 = c^2

For example, 3^2 + 4^2 = 9 + 16 = 25 = 52.

There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.

My solution is in 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;

Since "goto" statements are not very popular among c++ programmers, i would like to know, if this could be considered a reasonable use of "goto". Or if there is a better solution for the problem that doesn't need "goto". By that I don't mean a solution which just avoids "goto", but which avoids "goto" in a way that improves the algorithm.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

情泪▽动烟 2024-08-01 16:23:37

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;
}

return is a "structured" goto which many programmers find more acceptable! So:

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;
}
醉殇 2024-08-01 16:23:37

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

顺便说一句,反对 goto 的居高临下的说教通常来自那些只是鹦鹉学舌地模仿他们听到别人说或读到的东西的人。

In my opinion it's fine to use goto in a situation like this.

Btw, the condescending preaching against goto usually comes from people who just parrot what they heard others say or read somewhere..

止于盛夏 2024-08-01 16:23:37

请参阅此问题 关于打破 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 并不像杀死小猫那么糟糕。 但已经很接近了。

See this question about breaking out of 2 loops. There are much better answers provided than using a goto.

The best answer provided is to place your second loop into a function, and call that function from inside your first loop.

code copied from mquander's response

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;
    }
}

Though I do feel that using a goto in this case isn't quite as bad as killing kittens. But it's close.

陈甜 2024-08-01 16:23:37

我想不出更好的选择。 但不使用 goto 的另一种选择是修改第一个 for 循环:

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

然后从第二个 for 循环中 break 出来-环形。 假设在第二个 for 循环被 break 破坏后,结果永远不会是 -1,那么这将起作用。

I can't think of a better alternative. But one alternative not using goto would be modifying the first for-loop:

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

Then break out of the second for-loop. That will work assuming the result will never be -1 after the second for-loop has been broken by break.

千笙结 2024-08-01 16:23:37

您可以在顶部声明一个 boolfound = false ,然后添加 && !found 到你的 for 循环条件(在 a b 之后),然后在你当前的 goto 位置将found 设置为 true。 然后使你的输出以发现为真为条件。

You could declare a bool found = false at the top and then add && !found to your for loop conditionals (after a < sum and b < sum) and then set found to true where your current goto is. Then make your output conditional on found being true.

等风来 2024-08-01 16:23:37
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

无论如何我喜欢 gotos!

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);

Also optimized result out.. :P

Anyway i love gotos!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文