Partage
  • Partager sur Facebook
  • Partager sur Twitter

Decomposer un nombre en produit de facteur premier...

ex : 30 = 2 * 3 * 5

    18 janvier 2006 à 17:16:48

    Salut ! Je vous propose ici un petit code très simple mais bien sympa (puisque très rapide) qui permet de decomposer un nombre en produit de facteur 1er :
    30 = 2 * 3 * 5
    60 = 2 * 2 * 3 * 5

    Voici le code :

    #include <cstdlib>
    #include <iostream>

    using namespace std;
    long diviseur = 0;

    // ---------------------Fonction
    // Factor--------------------------------------

    void
    factor(long nombre)
    {
            while (diviseur < nombre) {
                    for (diviseur = 2; nombre % diviseur != 0; diviseur++) ;
                    if (diviseur * diviseur == nombre) {
                            printf("%ld * %ld\n\n", diviseur, diviseur);
                    } else if (nombre == diviseur) {
                            printf("%ld\n\n", diviseur);
                    } else {
                            printf("%ld * ", diviseur);
                    }
                    nombre = nombre / diviseur;

            }
    }


    // -------------------------Fin de la fonction, debut
    // Main--------------------

    int
    main(int argc, char *argv[])
    {
            long nombre;

            printf("           .::SuPeR FacToR By Bork0::. \n\n");
            printf("Le log decompose un nombre en un produit de facteur premiers !!\nTapez un nombre : ");
            scanf("%ld", &nombre);
            printf("%ld = ", nombre);
            factor(nombre);
            system("PAUSE");
            return EXIT_SUCCESS;
    }
                                           
                                       


    Enjoy !

    Voila ! Si vous avez des idées d'amélioration, hesitez pas a les dire !
    • Partager sur Facebook
    • Partager sur Twitter
      18 janvier 2006 à 17:31:18

      Mais pourquoi faire du C++ si c'est juste pour avoir un using namespace std; et un return EXIT_SUCCESS;...?
      Et avec ton code, 25 = 5 * 1, une petite modif à faire dans l'algo donc.

      Pour ton problème, remplace le contenu du while par
      nombre /= diviseur;
      printf("%ld", diviseur);
      if(nombre != 1)
          printf(" * ");
      • Partager sur Facebook
      • Partager sur Twitter
        18 janvier 2006 à 17:33:18

        Bon je vais essayer de regler le problème du 5 * 1 = 25.. (assez simple je pense ! )
        • Partager sur Facebook
        • Partager sur Twitter
          18 janvier 2006 à 17:37:11

          Une suggestion d'amélioration : Si tu as testé tous les nombres inférieurs à la racine carrée de nombre, le nombre qui reste est premier, et tu peux l'afficher directement.

          Et hop, pas mal de temps de gagné.

          Autre chose : une fois que tu as testé la division par deux, tu es sûr que le nombre restant ne peut plus être divisé par un multiple de deux. Tu peux donc faire avancer tes diviseur par pas de deux.

          Et hop, encore la moitié du temps de gagné.

          • Partager sur Facebook
          • Partager sur Twitter
            18 janvier 2006 à 17:49:58

            SuperMat j'ai essayé d'appliquer ta technique, pour la racine en effet ca va plus vite, seuleument le prog continue a chercher et veut plus se fermer..
            Pour la technique des +=2, ca fausse tout le programme

            je pense que ca doit venir de moi, que je les met mal en application, donc je te laisse faire !
            • Partager sur Facebook
            • Partager sur Twitter
              18 janvier 2006 à 19:58:21

              Un petit programme en caml, programmé à l'instant :
              let facteurs_premiers nombre =
                let rec facteurs_premiers_aux n avancee resultats =
                  if avancee*avancee > n then n::resultats
                  else if n mod avancee = 0 then
                    facteurs_premiers_aux (n/avancee) avancee (avancee::resultats)
                  else facteurs_premiers_aux n (avancee+1) resultats
                in
                  List.rev (facteurs_premiers_aux nombre 2 [1])
              in

              List.iter (Printf.printf "%d\n") (facteurs_premiers (read_int()));;
              • Partager sur Facebook
              • Partager sur Twitter
                18 janvier 2006 à 20:07:30

                Citation : BorkO

                le prog continue a chercher et veut plus se fermer..



                Je vois pas... sûrement une erreur dans la condition d'arrêt mais sans voir le code je peux pas dire.

                Citation : BorkO

                Pour la technique des +=2, ca fausse tout le programme



                Je pense savoir d'où ca vient. Avec cette amélioration, tu dois d'abord diviser par 2 autant de fois que possible. Puis seulement, tu entre dans ta boucle principale en commençant à 3 et en incrémentant par pas de 2. Si tu as "bêtement" changé diviseur++ par diviseur+= 2 tu tentes alors de diviser par 2, puis par 4, puis par 6 etc ce qui évidemment n'est pas souhaitable ^^

                Citation : BorkO

                donc je te laisse faire !

                Tu entends quoi par là?
                • Partager sur Facebook
                • Partager sur Twitter
                  19 janvier 2006 à 16:49:16

                  Ben deja si tu pouvais expliquer ou faire les changements..
                  • Partager sur Facebook
                  • Partager sur Twitter
                    19 janvier 2006 à 19:59:53

                    Je fais ca sans vérifier.


                    void factor(long nombre)
                    {
                            long accu = 0;
                            long diviseur;
                            long div_carre;

                            // d'abord on teste la division par deux.
                            while(nombre %2 == 0)   // tant que nombre est pair
                            {
                                nombre /= 2;
                                accu++;
                            }
                            if(accu != 0)
                                 printf("2 \^ %d \n", accu);

                            // on commence la boucle à 3
                            diviseur = 3;
                            div_carre = diviseur * diviseur;

                            while(div_carre <= nombre)
                            {
                                  accu = 0;
                                  while(nombre % diviseur == 0)
                                  {
                                      nombre /= diviseur;
                                      accu++;
                                  }
                                  if(accu != 0)
                                      printf("%d \^ %d\n", diviseur, accu);

                                  diviseur += 2;
                                  div_carre = diviseur * diviseur;
                             }

                             // Ce qu'il reste dans nombre est forcément premier.
                             printf("%d\n", nombre);
                           
                    }


                    Voila il y a longtemps que j'ai plus fait de C alors j'espère que ca va aller. J'ai mis \^ dans mes printf car je pense qu'il faut un échappement pour ^. Si tu as un affichage bizarre vire le slash.

                    J'ai refait ce code de mémoire, j'ai eu examen aujourd'hui et j'en ai encore un demain donc ne pas frapper si c'est pas bon ^^

                    Il vaudrait mieux aussi que cette routine soit une fonction. C'est-à-dire qu'elle retourne un résultat facilement exploitable plutôt que d'afficher bêtement la décomposition. C'est d'ailleurs ce que bluestorm a fait il me semble. Le Caml dans toute sa splendeur :)
                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 janvier 2006 à 7:30:58

                      blestorm> je savais pas que la syntaxe de OCalm était à ce point éloignée de celle du C++ (ca ca veut dire jay rien compris à ton code :D )
                      • Partager sur Facebook
                      • Partager sur Twitter
                        20 janvier 2006 à 23:38:05

                        Hum, pourtant j'ai fait des efforts :p

                        Voici une version simplifiée au max :
                        let facteurs_premiers nombre =
                          let rec facteurs_premiers_aux n avancee =
                            if avancee*avancee > n then ()
                            else if n mod avancee = 0 then begin
                              Printf.printf "%d\n" avancee;
                              facteurs_premiers_aux (n/avancee) avancee
                            end
                            else facteurs_premiers_aux n (avancee+1)
                          in
                           facteurs_premiers_aux nombre 2
                        in

                        facteurs_premiers (read_int());;


                        Voici une version qui prend en compte le "passage de 2 en 2" de SuperMat :
                        let facteurs_premiers nombre =
                          let rec facteurs_premiers2 n avancee resultats =
                            if avancee*avancee > n then (n::resultats)
                            else if n mod avancee = 0 then
                            facteurs_premiers2 (n/avancee) avancee (avancee::resultats)
                            else facteurs_premiers2 n (avancee + (if avancee > 2 then 2 else 1)) resultats
                          in List.rev (facteurs_premiers2 nombre 2 [1])
                        in
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          20 janvier 2006 à 23:45:02

                          Jamais je n'irai manquer de respect à un type qui sait écrire un code pareil dans un tel langage, mais j'aimerai quand même lui demander l'intérêt de poster un code source que peu savent lire ici pour la simple raison qu'ils ne sont pas habitués aux fonctions récursives.

                          Qui, de plus, n'appartiennent pas vraiment au style impératif du C, si je ne m'abuse.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            20 janvier 2006 à 23:57:01

                            Je la refais en impératif :
                            #include <stdio.h>

                            void facteurs_premiers(int nombre)
                            {
                                int n=nombre, avancee=2;
                                printf("1\n");
                                while(avancee*avancee <= n)
                                {
                                        if (0 == (n % avancee))
                                        {
                                                n /= avancee;
                                                printf("%d\n", avancee);
                                        }
                                        //elseif (avancee>2) avancee += 2;
                                        else avancee++;
                                }
                                printf("%d"\n, n);
                            }

                            int main(void)
                            {
                                    int nombre;
                                    scanf("%d", &nombre);
                                    facteurs_premiers(nombre);
                                    return 0;
                            }
                            • Partager sur Facebook
                            • Partager sur Twitter
                              21 janvier 2006 à 12:44:55

                              Borko > j'espère que tu sais que tu codes en C ?? parceque j'ai remarqué que tu utilises assez souvent les balises Cpp pour les codes en C que tu postes et je trouves ça moche
                              • Partager sur Facebook
                              • Partager sur Twitter
                                21 janvier 2006 à 14:40:32

                                Citation : Neodyme

                                Borko > j'espère que tu sais que tu codes en C ?? parceque j'ai remarqué que tu utilises assez souvent les balises Cpp pour les codes en C que tu postes et je trouves ça moche


                                Hum, rz0 utilise aussi les balises Cpp, je crois. Mais je crois qu'il sait qu'il code en C :).
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  21 janvier 2006 à 15:07:45

                                  en même temps il fout pas "#include <iostream>" au début de ses codes, le rz0 :-°
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    21 janvier 2006 à 15:44:24

                                    Citation : bluestorm

                                    en même temps il fout pas "#include <iostream>" au début de ses codes, le rz0 :-°


                                    Hum, oui j'avais pas vu, mais c'est pour dire que la balise n'a pas de rapport avec le langage :euh:
                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Decomposer un nombre en produit de facteur premier...

                                    × 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