Partage
  • Partager sur Facebook
  • Partager sur Twitter

Informations structurées ,

nombre premier

Sujet résolu
    20 septembre 2019 à 13:19:50

    Bonjour à tous , j'étudie l'ouvrage de Claude Delannoy et j'en suis arrivé aux exercices concernant les informations structurées , dont un qui est de définir si un nombre entré en saisie est un nombre premier ou pas je vous poste mon code qui réagi bien

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        printf("Le but de ce programme est de determiner si un nombre entier donner en saisie est premier uo pas\n\n\n");
      unsigned int saisie=0 , continuer=9;
       while(continuer>0)
       {
    
    
       printf("Entrer votre nombre :");
       scanf("%d",&saisie);
    
       int operande_1=1 , operande_2 =0 ,nbreDeSaisie=0 , resultat=0;
       while(operande_1<=200)
       {
           for(operande_2=1 ; operande_2<=200 ; operande_2++)
           {
               resultat = operande_1 * operande_2;
               if( resultat==saisie) nbreDeSaisie++ ,printf("%d * %d = %d\n",operande_1,operande_2,resultat);
           }
           operande_1++;
       }
       if(nbreDeSaisie >=3||nbreDeSaisie==1)printf("Ce nombre n'est pas un nombre premier\n\n");
       else printf("Ce nombre est  un nombre premier\n\n");
       continuer--;
       }
      return 0;
    }
    

    Mais j'ai donc été voir pour les corrections et le code est beaucoup court que le mien :

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    int main()
    {
       int n ,d;
    
       do
       {
           printf("donner un entier superieur a 2 : ");
           scanf("%d",&n);
       }while(n<=2);
       d=2;
       while( (n%d) && (d<=sqrt(n)) )d++;
    
       if(n%d) printf("%d est premier",n);
       else printf("%d n'est pas premier",n);
    
    
       return 0;
    }
    

    Voilà pourquoi je poste ce post pour essayé de de comprendre pourquoi la boucle while , pour qu'il y est incrémentation de 'd' il faut que les deux expressions valent 1 , j'ai retiré cette boucle et le code fonctionne tout autant , alors pourquoi cette boucle ???:o


    • Partager sur Facebook
    • Partager sur Twitter

    C OK ;-)

      20 septembre 2019 à 13:51:36

      Pour faire des progrès, prenez les livres de Delannoy d'une main, et servez-vous de l'autre pour soulever le couvercle de la poubelle.

      Calculer la racine carrée à chaque tour de boucle, sans déconner....

      -
      Edité par michelbillaud 20 septembre 2019 à 13:53:03

      • Partager sur Facebook
      • Partager sur Twitter
        20 septembre 2019 à 14:20:33

        bonjour michelbillaud ,merci de ta réponse,franchement je trouve que c'est un bon ouvrage j'ai appris plusieurs choses concernant les opérateurs(leurs priorités) et les expressions , mais on n'est bien d'accord sur ce code je pense qu'il y a moins compliqué, je n'aurais jamais pensé à calculer la racine carrée, bon après je débute ....mais lors de mes recherches j'étais loin de penser à cela, et peux-tu me donner ton avis sur mon code...merci

        -
        Edité par COUZ-1 20 septembre 2019 à 14:24:14

        • Partager sur Facebook
        • Partager sur Twitter

        C OK ;-)

          20 septembre 2019 à 16:07:56

          Il n'est pas indenté, les variables portent des noms fantaisistes (continuer pour un nombre de coups restants ou sans significations operande_2.

          Utilisation dévoyée de  inst1, inst2  pour faire des blocs (dans partie "alors" d'un test). Au lieu de  { inst1; inst2; }

          Tres inefficace :operande 2 s'obtient par un simple division, au lieu d'une boucle.

          Enfin, ça fait autre chose que ce qui est demandé, afficher la décomposition en 2 facteurs n'en fait pas partie.

          -
          Edité par michelbillaud 20 septembre 2019 à 16:10:23

          • Partager sur Facebook
          • Partager sur Twitter
            20 septembre 2019 à 22:01:35

            Je trouve que tu te compliques la vie... (À vrai dire je ne comprends pas trop ce que fait ton programme.) Un nombre premier est un nombre qui n'admet aucun diviseur strictement compris entre 1 et lui même (supposé >= 2.) Du coup on peut écrire un programme naïf qui est tout simple en parcourant tous les diviseurs potentiels entre 2 et n-1.

            Bien sûr ce n'est pas optimal : ce serait plus optimal si on s'arrêtait à la racine carrée, et encore plus si on ne testait que les diviseurs potentiels qui sont déjà des nombres premiers.

            Avec l'algorithme naïf, on peut faire ce genre de chose :

                    int d = 2 ;
                    bool non_div = true ; // on n'a pas encore trouvé de diviseur
                    while (non_div && d < n)
                    {
                        non_div = (n%d != 0) ; // vrai si n n'est pas divisible par d
                        d++ ;
                    }
            

            (Ici le nombre n à tester est supposé >=2.) Et si on veut tenir compte du coup de la racine carrée, la différence est minime (c'est presque un jeu : trouver les deux différences) :

                    int d = 2 ;
                    bool non_div = true ; // on n'a pas encore trouvé de diviseur
                    while (non_div && d*d <= n)
                    {
                        non_div = (n%d != 0) ; // vrai si n n'est pas divisible par d
                        d++ ;
                    }
            

            (J'ai testé ça, je crois que ça marche.) (Comme on le voit, je suis un adepte des noms de variables courts et pas forcément très explicites...) (Je ne suis pas sûr que remplacer 1 calcul de racine carrée par ~n multiplications d*d soit judicieux, c'est parce que le but était de mettre en œuvre un algorithme naïf facilement accessible à un débutant qui ne connaît pas forcément <math.h>.)

            -
            Edité par robun 20 septembre 2019 à 22:08:32

            • Partager sur Facebook
            • Partager sur Twitter
              21 septembre 2019 à 7:31:28

              La forme suivante est plus simple et plus lisible

              while ( d*d <= n && ! divisible_par(n, d)) {
                 d++;
              }

              Avec

              bool divisible_par(int n, int  q) {
                 return n % q == 0;
              }


              Si le débutant n'a pas l'idée de s'arrêter à la racine carrée, c'est qu'il n'a pas les connaissances de base  sur les nombres premiers.  Et donc que l'exercice est très mal choisi.

              Ce genre d'exercices, ça remonte à l'antiquité de l'informatique, quand le public ciblé  etait des élèves ingénieurs qui apprenaient à programmer en fortran. Avec un bagage scientifique et mathématique, donc.

              -
              Edité par michelbillaud 21 septembre 2019 à 7:37:01

              • Partager sur Facebook
              • Partager sur Twitter
                22 septembre 2019 à 9:29:23

                Bonjour michelbillaud , bonjour robun,

                Pour savoir ce qu'était un nombre premier j'ai suis allé sur le web pour y prendre des informations , et celles qui sont revenues plus souvent sont qu'un nombre premier est un nombre divisible par 1 ou par lui même et je suis parti sur cette base pour l'exercice , c'est vrai que le restant d'une division si il est différent de 0 le nombre est premier ... moi je me suis lancé sur les multiplicateurs d'un nombre, enfin bref j'ai encore du boulot(je vais revoir cette exercice et éventuellement modifié les autres) ;) ,

                merci de vos commentaires et bon dimanche a vous  .

                -
                Edité par COUZ-1 22 septembre 2019 à 9:41:12

                • Partager sur Facebook
                • Partager sur Twitter

                C OK ;-)

                  22 septembre 2019 à 9:50:46

                  Ce que je veux dire, c'est que c'est complètement stupide de la part de l'auteur de mettre un exercice portant sur un domaine particulier (ici l'arithmétique) dans un bouquin qui se veut destiné à des gens qui, a priori, ne connaissent pas ce domaine.

                  Le but de ce genre d'exercice, c'est de leur faire pratiquer les boucles, certainement pas de les faire galérer en leur parlant de trucs qu'ils ne connaissent pas. 

                  Quand j'ai commencé à enseigner, c'était de la formation continue avec des gens avec un background scientifique. Donc en avant les nombres premiers, les pgcd, les suites, les séries et l'algebre linéaire. Donc ça allait.

                  Par exemple tu prends un exercice innocent : faire afficher 1/1 + 1/2 + 1/3 + .... 1/N   avec N = 10. Puis N=1000. Puis N=100000. Conclusions ?

                  Le joyeux apprenti programmeur, il va écrire la boucle, et constater que quand N grandit, au bout d'un moment ça ne bouge plus. Il va en tirer la conclusion que, ayé, on a trouvé la limite (parce qu'avant on lui a fait calculer 1 + 1/2 + 1/4 + 1/8 ... qui converge vers 2 comme tout le monde sait. Un gateau, plus un demi gateau, plus un quart de gateau, ok).

                  Sauf que c'est faux.

                  S'il a fait un peu de maths, il devrait savoir que la somme des inverses (la série harmonique), ça diverge. Donc c'est évident qu'il y a un truc qui va pas. Et là, ça va être l'occasion de parler de précision dans la représentation des flottants, et de l'importance de l'ordre de calcul (spoiler : il faut partir de N et revenir vers 1).

                  Mais ça, si il ne connait pas, ça lui passe complètement au dessus de la tête (probablement le cas de la plupart des lecteurs ici :-) c'est fait exprès).

                  Maintenant tu fais faire ça à un bachelier moyen, il ouvre les yeux comme des soucoupes en te demandant ce que ça veut dire "diverger". Donc tu changes d'exercice. Convergence et divergence, c'est interessant, mais c'est pas le sujet que tu veux lui apprendre.

                  -
                  Edité par michelbillaud 22 septembre 2019 à 9:56:36

                  • Partager sur Facebook
                  • Partager sur Twitter
                    22 septembre 2019 à 11:34:45

                    J'étudie  , enfin j'essaie  d'apprendre la programmation en C en tant qu'autodidacte, je commence vraiment à la base ( ce que je veux te dire c'est que je n'ai aucune formation scientifique)  , j'ai commencé avec Openclassroom, mais ayant le sentiment d'aller trop vite sans trop comprendre j'ai repris les cours d'OP au début et j'ai trouvé par hasard l'ouvrage de Claude Delannoy et franchement j'ai appris des choses que l'on n'avait pas vu avec OP : comme par exemple, tu cites la précision des flottants et grâce a cela j'ai pu voir " l'erreur de troncature" , "la notation exponentielle" , " le format libre d'écriture ( peut-être pour cela que mon code est mal indenté) " et d'autres encore ,  peut-être que l'exercice n'est pas adapté à mon niveau , mais ça fais faire des exercices , permet la pratique , désolé si mon code n'étais pas très lisible et très clair:D, en tout cas  cool que vous répondiez

                    En tout cas je comprends ce que tu explique dans ton post.

                    • Partager sur Facebook
                    • Partager sur Twitter

                    C OK ;-)

                      22 septembre 2019 à 12:14:07

                      SI la référence c'est le "cours" d'openclassrooms, forcément n'importe quel bouquin c'est mieux :-)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        22 septembre 2019 à 12:23:30

                        Lol :lol:, ben oui on n'apprend les concepts sans trop les décrire et hop aux exos cash !c'est pour ses raisons que jai eu le sentiment d'apprendre sans vraiment comprendre avec Delannoy par exemple, j'ai apprit la fonction scanf , gabarit, précision , les codes de format… 

                        Tu enseigne  la programmation informatique uniquement?

                        • Partager sur Facebook
                        • Partager sur Twitter

                        C OK ;-)

                          22 septembre 2019 à 13:30:37

                          Divers sujets informatiques. Pas la litterature ouzbeque medievale.
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Informations structurées ,

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown