2010-05-10 74 views
2

我做了一个程序,返回产品a b c其中a,b,c是毕达哥拉斯三元组并加起来为1000.程序确实输出了正确的答案但是做了两次。我很好奇这是为什么。玩弄它之后有点我发现它打印出来当a = 200 B = 375 C = 425,并再次α= 375 B = 200 C = 425为什么打印出来的答案是两次?

bool isPythagTriple(int a, int b, int c); 

int main() 
{ 

    for(int a = 1; a < 1000; a++) 
    { 
     for(int b = 1; b < 1000; b++) 
     { 
      for(int c = 1; c < 1000; c++) 
      { 
       if(((a+b+c)==1000) && isPythagTriple(a,b,c)) 
       { 
        cout << a*b*c << " "; 
        break; 
       } 
      } 
     } 
    } 

    return 0; 
} 

bool isPythagTriple(int a, int b, int c) 
{ 
    if((a*a)+(b*b)-(c*c) == 0) 
     return true; 
    else 
     return false; 
} 
+0

把你的代码到一个代码块,你缩进一切4个空格。 101010按钮可以帮你完成 - 粘贴代码,然后选择它并点击101010按钮。 – 2010-05-10 03:30:24

+2

...将“蛮力”变成“蛮力”...;) – msw 2010-05-10 03:38:32

+3

如果你的问题还没有通过清理你的代码和调整你的循环边界来解决,这实际上是一个非常好的地方被误解的“goto”声明的奇迹。如果不是针对这里提出的各种修复方法,那么突破多重嵌套循环是在像C或C++这样的语言中使用'goto'的好地方。 – 2010-05-10 06:03:08

回答

8

打破,在这种情况下,只会突破c循环,而不是ba循环。

速战速决是保证你不开始超过每个变量大于或等于先前得到重复(所以b是从来没有少于ac是从来没有少于b)。

另外,其实你可以得到完全摆脱c环,因为有中c只有一个值,其有效期为一个给定的a,b对(除非a + b + c > 1000在这种情况下是没有的)。我会尝试这样的:

for (int a = 1; a < 1000; a++) { 
    for (int b = a; b < 1000; b++) { 
     int c = 1000 - a - b; 
     if (c >= b) { 
      if (isPythagTriple (a,b,c)) { 
       cout << a << " " << b << " " << c << " " << a*b*c << std::endl; 
      } 
     } 
    } 
} 

的整体效果是减少一个十亿(短秤)的总环数为大约50万,因此由约99.95%减少了 - 这应该是一个很小的快一点:-)


,并可能与杰里棺材的建议,使其更快,以及(和内联建议编译器),一个完整的程序:

#include <iostream> 

inline bool isPythagTriple(int a, int b, int c) { 
    return a * a + b * b == c * c; 
} 

int main() { 
    for(int a = 1; a < 1000; a++) { 
     for(int b = a; b < 1000; b++) { 
      int c = 1000 - a - b; 
      if (c >= b) { 
       if (isPythagTriple(a,b,c)) { 
        std::cout << a << " " << b << " " << c << " " 
         << a*b*c << std::endl; 
       } 
      } 
     } 
    } 
    return 0; 
} 

这需要平均(系统+用户)在我的包装盒上的平均时间为0.004秒,平均每个平均需要2.772秒(每个样本10个样本)。并不是说它真的很重要,除非你多次运行它,当然。

代码的输出,符合市场预期:

200 375 425 31875000 
+0

不错的优化,有趣的多级别休息模拟 – msw 2010-05-10 03:44:30

+0

是的,意外地留下了从我以前认识到不符合规格的答案以前的化身。现在已经修复,同时还有c-big-than-b位。 – paxdiablo 2010-05-10 03:47:16

2

这是怎么breakcontinue工作 - break只退出最内圈。阅读讨论on this question的一些替代方案。

+0

哦,我明白了,谢谢你的快速回答! – rEgonicS 2010-05-10 03:31:41

0

之所以出现这种情况是因为你只跳出内部循环(对于C)的。外环继续运行并重新进入内环,再次满足条件。有很多值增加到1000,你正在捕捉其中的一些 - 你已经抓住了2,正如你的打印所示。如果只需要输出值的第一个组合,则可以使用“返回”而不是中断。

至于“代码块”我不确定你的意思..你已经似乎知道写功能。如果你的意思是一个示波器模块,那么你只需在大括号中加上关注的代码 - > {}

E.g.

{ int i = 0; i ++; }

0

要防止解决方案的多次排序,请确保c >= b >= a。您可以通过改变下限做到这一点:

for(int a = 1; a < 1000; a++) { 
     for(int b = a; b < 1000; b++) { 
      for(int c = b; c < 1000; c++) { 
9

只是为了它的价值,我会写这样的功能:

bool isPythagTriple(int a, int b, int c) 
{ 
    if((a*a)+(b*b)-(c*c) == 0) 
     return true; 
    else 
     return false; 
} 

更多类似这样的:

bool isPythagTriple(int a, int b, int c) { 
    return a*a+b*b==c*c; 
} 
+0

+1使代码更具可读性,在我看来这总是值得追求的。 – paxdiablo 2010-05-10 05:58:11