2010-05-10 75 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