2010-05-10 4 views
2

J'ai créé un programme qui renvoie le produit b c où a, b, c sont des triplets pythagoriciens et totalisent 1000. Le programme affiche la bonne réponse mais le fait deux fois. J'étais curieux de savoir pourquoi c'est ainsi. Après avoir joué avec un peu j'ai découvert qu'il imprime quand a = 200 b = 375 c = 425. Et encore une fois quand a = 375 b = 200 c = 425.Pourquoi la réponse est-elle imprimée deux fois?

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

Pour mettre votre code dans un bloc de code, vous indentez tout 4 espaces. Le bouton 101010 fait cela pour vous - collez le code, puis sélectionnez-le et cliquez sur le bouton 101010. –

+2

... mettre la "brute" en "force brute" ...;) – msw

+3

Si votre problème n'était pas déjà résolu en nettoyant votre code et en ajustant vos limites de boucle, ce serait en fait un très bon endroit pour jaser les merveilles de la déclaration «goto» mal comprise. Si ce n'était pas pour les différentes corrections suggérées ici, sortir des boucles multi-imbriquées est un excellent endroit pour utiliser 'goto' dans des langages comme C ou C++. –

Répondre

8

La rupture, dans ce cas, ne sortira que de la boucle c, et non des b et a.

Une solution rapide est de vous assurer que vous ne recevez pas les répétitions en commençant chaque variable supérieure ou égale à la précédente (si b est jamais moins de a et c est jamais moins de b).

De plus, vous pouvez réellement se débarrasser de la boucle complètement c car il n'y a qu'une seule valeur de c qui est valable pour une paire donnée a,b (à moins a + b + c > 1000 auquel cas il n'y en a pas). Je voudrais essayer quelque chose comme:

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

L'effet global de c'est de réduire le nombre total de la boucle d'un milliard (courte échelle) pour le réduire d'un demi-million donc d'environ 99,95% - qui devrait être un tout petit peu plus vite :-)


et rendant potentiellement plus rapide avec la suggestion de Coffin Jerry ainsi (et une suggestion en ligne au compilateur), un programme complet:

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

qui prend 0,004 secondes en moyenne (système + utilisateur) sur ma boîte, avec l'original prenant environ 2,772 secondes en moyenne (dix échantillons chacun). Pas que ça compte vraiment, à moins que vous ne l'utilisiez de nombreuses fois, bien sûr.

La sortie de ce code est, comme prévu:

200 375 425 31875000 
+0

belle optimisation, drôle multi-niveau pause simulation – msw

+0

Ouais, accidentellement laissé cela d'une incarnation précédente de la réponse que j'ai réalisé ne répond pas aux spécifications. Correction maintenant, avec le bit c-plus-que-b aussi bien. – paxdiablo

2

Voici comment break et continue work - break ne sort que de la boucle la plus interne. Lisez la discussion on this question pour des alternatives à cela.

+0

Oh je vois, merci pour la réponse rapide! – rEgonicS

0

La raison pour cela est parce que vous ne sortir de la boucle interne (pour c). Les boucles externes continuent de courir et rentrent dans la boucle interne, répondant à nouveau aux conditions. Il y a de nombreuses valeurs qui s'ajoutent à 1000 et vous en attrapez certaines - vous en avez pris 2, comme l'indique votre impression. Vous pouvez utiliser "return" au lieu de break si vous ne voulez que la sortie de la première combinaison de valeurs. Comme pour le "bloc de code" je ne suis pas sûr de ce que vous voulez dire .. Vous semblez déjà savoir écrire des fonctions. Si ce que vous voulez dire est un bloc de portée, alors vous entourez simplement le code de préoccupation dans des accolades -> {

E.g.

{ int i = 0; i ++; }

0

Pour éviter les multiples commandes des solutions, assurez-vous que c >= b >= a.Vous pouvez le faire en changeant les bornes inférieures:

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

Juste pour ce que ça vaut, j'écrire cette fonction:

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

Plus comme ceci:

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

+1 pour rendre le code plus lisible, c'est toujours une poursuite digne de mon avis. – paxdiablo

Questions connexes