IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Factoriser un programme


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Agronome
    Inscrit en
    Septembre 2018
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Agronome
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Septembre 2018
    Messages : 97
    Par défaut Factoriser un programme
    Bonjour,

    Voici un programme que j'ai factorisé. J'ai ajouté les fonctions qui remplace des bouts de code identique et j'ai laissé ces bouts de code en commentaire.

    D'avance merci pour votre relecture

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    #include <stdio.h>
    #include <stdlib.h>
    #define INFINITY 100
     
    double fact(int n);
    int fact2(int n);
     
    int main(void){
        //Estimation de la valeur de e: Somme_{n=0}^INFINI 1/n! La valeur de e est 2.718282
        double e = 0;
        int n = 0;
        while(n<INFINITY){
            /*
            double fact_n = 1;
            int i;
            for(i=1;i<=n;i++){
                fact_n *= i;
            }
            */
            e+= 1/fact(n);
            n++;
        }
     
        printf("La valeur de e est %lf\n\n----------------\n\n",e);
     
        //Nombre de podiums de 3 athlètes possibles parmi n: 
        // n!/(n-3)!
        int athletes;
        printf("Combien y a-t-il d'athlètes en compétition ?\n");
        scanf("%d",&athletes);
    	/*
        int fact_athletes = 1;
        int fact_athletes_moins = 1;
        */
        if(athletes>=3){   
           /*
            int i;
            for(i=1;i<=athletes;i++){
                fact_athletes *= i;
            	       }
            for(i=1;i<=athletes-3;i++){
                fact_athletes_moins *= i;
            }    
            printf("Nombre de podiums possibles:%d\n",fact_athletes/fact_athletes_moins);
            */
            printf("Nombre de podiums possibles:%d\n",fact2(athletes)/fact2(athletes-3));
        }
        else{
            printf("Pas assez d'athlètes pour remplir le podium !\n");
        }
        return EXIT_SUCCESS;
     
    }
     
    /**************************************Les fonctions**************************************/
     
    //factorielle
    //PRE :/
    //POST : renvoi la factorielle (reel) du nombre n
    double fact(int n){
    		double r;
    //invariant : n est plus grand que 0
    		for(r=1;n>0;n--){
                    r*=n;
                    }
                    return r;
     }
    //PRE :/
    //POST : renvoi la factorielle (entier) du nombre n
    int fact2(int n){
    		int r;
    //invariant : n est plus grand que 0
    		for(r=1;n>0;n--){
                    r*=n;
                    }
                    return r;
       }

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Citation Envoyé par Magnum8760 Voir le message
    J'ai ajouté les fonctions qui remplace des bouts de code identique et j'ai laissé ces bouts de code en commentaire.
    Tu veux dire qu'avant tu calculais la factorielle à chaque fois et là tu l'as mise en fonction. C'est évidemment ce qu'il faut faire surtout si tu l'utilises plusieurs fois.

    Citation Envoyé par Magnum8760 Voir le message
    D'avance merci pour votre relecture
    Et qu'on fasse quoi après avoir relu ? Te donner nos remarques ?
    Ben moi j'en ai 3 sur du détail
    1. pourquoi deux fonctions factorielles qui font la même chose ?
    2. pourquoi ne pas calculer la factorielle en "unsigned" ce qui te donnerait de la valeur en plus ?
    3. c'est quoi ces "*******" dans ton code ?


    Et une remarque principale: la factorielle monte de suite très très haut ce qui ne te permet pas de calculer des arrangements très grands. Par exemple A(3, 20) est impossible à calculer avec ton programme.
    Or, A(3, 20) n'est pas vraiment très grand lui. Il vaut à peine 6840 ce qui est très facilement atteignable même avec un short.
    Sauf qu'au lieu de calculer 20! / 17!, j'ai préféré calculer 18*19*20 qui est la simplification de cette fraction.

    Donc au lieu de passer par deux factorielles, tu pourrais passer par une vraie fonction "arrangement" qui, elle, calcule selon ce principe.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Puisque tu as demandé une relecture, j'ajoute :

    • Citation Envoyé par Magnum8760 Voir le message
      Bonjour,

      Voici un programme que j'ai factorisé.
      Attention aux termes employés : « factoriser » a un sens bien précis selon le contexte, y compris dans celui de la programmation informatique. Ici tu as plutôt écrit un programme qui calcule, entre autres, la factorielle d'un nombre naturel. On conviendra qu'il s'agit d'une toute autre chose.

    • n<INFINITY : cette expression, au sens mathématique et si n appartient à l'ensemble des entiers naturels, est par définition toujours vraie. Il serait avisé de nommer différemment la constante INFINITY, d'autant que tu admets toi-même qu'il s'agit d'une approximation de la valeur de e (qui doit être estimé à strictement zéro d'ailleurs, vu le code) ;

    • Citation Envoyé par Magnum8760 Voir le message
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      //factorielle
      //PRE :/
      //POST : renvoi la factorielle (reel) du nombre n
      double fact(int n){
      		double r;
      //invariant : n est plus grand que 0
      		for(r=1;n>0;n--){
                      r*=n;
                      }
                      return r;
       }
      Pour faire respecter (et documenter) les invariants en C, on utilise souvent une méthode très simple :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      #include <assert.h>
       
      int fact(int n) {
          assert(n >= 0);
       
          // compute and return factorial(n)
      }
      Je te laisse consulter la page de manuel de la fonction / macro assert.

      Et bien entendu si l'on modifie, comme l'a précisé Sve@r, l'écriture de fact pour que le type de son paramètre soit un entier non signé alors l'invariant devient inviolable dans ce cas précis.

  4. #4
    Membre confirmé
    Homme Profil pro
    Agronome
    Inscrit en
    Septembre 2018
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Agronome
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Septembre 2018
    Messages : 97
    Par défaut
    Dans ce programme, deux fonctions identiques qui renvoient un unsigned int ou un float. C'est mieux, en effet.

    Par contre, en simplifiant la division de fact en multiplication, le resultat n'est pas toujours le meme (ex 20).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    #include <stdio.h>
    #include <stdlib.h>
    #define INFINITY 100
     
    float fact(int n);
    unsigned int fact2(int n);
     
    int main(void){
        //Estimation de la valeur de e: Somme_{n=0}^INFINI 1/n! La valeur de e est 2.718282
        float e = 0;
        int n = 0;
        while(n<INFINITY){
            e+= 1/fact(n);
            n++;
        }
        printf("La valeur de e est %lf\n\n----------------\n\n",e);
     
        //Nombre de podiums de 3 athlètes possibles parmi n: 
        // n!/(n-3)!
        int athletes;
        printf("Combien y a-t-il d'athlètes en compétition ?\n");
        scanf("%d",&athletes);
     
        if(athletes>=3){   
            printf("Nombre de podiums possibles:%d\n",fact2(athletes)/fact2(athletes-3));
            printf("Nombre de podiums possibles (en simplifiant la fraction de fact! par une multiplication):%d\n",(athletes-2)*(athletes-1)*athletes);
        }
        else{
            printf("Pas assez d'athlètes pour remplir le podium !\n");
        }
        return EXIT_SUCCESS;
     
    }
     
    /**************************************fonctions**************************************/
     
    //PRE :/
    //POST : renvoi la factorielle (reel) du nombre n
    float fact(int n){
    		double r;
    //invariant : n est plus grand que 0
    		for(r=1;n>0;n--){
                           r*=n;
                    }
                    return r;
                    }
    //PRE :/
    //POST : renvoi la factorielle (entier) du nombre n
    unsigned int fact2(int n){
    		int r;
    //invariant : n est plus grand que 0
    		for(r=1;n>0;n--){
                          r*=n;
                    }
                   return r;
                   }

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Magnum8760 Voir le message
    Par contre, en simplifiant la division de fact en multiplication, le resultat n'est pas toujours le meme (ex 20).
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(athletes>=3){   
            printf("Nombre de podiums possibles:%d\n",fact2(athletes)/fact2(athletes-3));
            printf("Nombre de podiums possibles (en simplifiant la fraction de fact! par une multiplication):%d\n",(athletes-2)*(athletes-1)*athletes);
        }
    Ben oui. Avec ta méthode, 20! / 17! n'est pas faisable tandis qu'en calculant (20-2)*(20-1)*20 ça donne bien 6840 comme je l'avais déjà dit.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Programme de boot qui passe la main à Windows
    Par Bob dans le forum Assembleur
    Réponses: 7
    Dernier message: 25/11/2002, 03h08
  2. [Kylix] Probleme d'execution de programmes...
    Par yopziggy dans le forum EDI
    Réponses: 19
    Dernier message: 03/05/2002, 14h50
  3. communication entre programmes
    Par jérôme dans le forum C
    Réponses: 12
    Dernier message: 16/04/2002, 08h05
  4. Comment débuter en programmation ?
    Par Marc Lussac dans le forum Débuter
    Réponses: 0
    Dernier message: 08/04/2002, 11h29
  5. [Kylix] icone associée à un programme
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo