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 :

Suite de Fibonacci


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 155
    Points : 90
    Points
    90
    Par défaut Suite de Fibonacci
    Bonjour,

    J'ai créer une petite fonction destinée à calculer le n-ième terme de la suite de Fibonacci : 1,1,2,3,5,8,13 ... (chaque terme égale la somme des deux précédents)

    Pourriez-vous y jeter un coup d'oeil (tout marche, tout fonctionne mais j'aimerais avoir votre avis ...) :

    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
     
    /* Suite de Fibonacci, chaque terme est égale à la somme de deux précdents : 1,1,2,3,5,8 ...
    Le n ième terme est donc la somme des termes (n-1) et (n-2) si n>2 (n entier positif) */
    long int fib(unsigned int n)
    {
         long int resultat=1;                    // Le n ième terme
         long int terme_1 = 1, terme_2 = 1;      // Les termes n-1 et n-2
     
         if (n < 3) return 1;
     
         resultat = 2;
         for (int C=3; C<=n; C++)
         {
             // n = (n -1) + (n - 2)
             resultat = terme_1 + terme_2;
             /* Logiquement, lorsqu'on passe au terme suivant, le terme (n-1)devient le terme (n - 2) et le terme (n - 2) devient le terme n */
             terme_1 = terme_2;
             terme_2 = resultat;
         }
         return resultat;
    }
    Est ce qu'il y certaines choses que j'ai faites de travers (niveau de l'algo) ? Y a il des améliorations a apportées ?

    merci

  2. #2
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Juin 2004
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2004
    Messages : 68
    Points : 86
    Points
    86
    Par défaut
    la première chose que tu peux changer c'est le type de retour etant donné que ce sera toujours un nombre >0 tu peux retourner un unsigned long de plus tu prends en paramètre un unsigned donc...

    en ce qui concerne la méthode en elle même étant donné que je n'ai codé fibonacci qu'en récursif je ne peux pas te dire si elle est bonne ou pas mais comme tu dis que cela fonctionne c'est que cela doit être vrai.

  3. #3
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Points : 2 757
    Points
    2 757
    Par défaut
    bonjour,

    la suite de Fibonacci commence à 0

    conditions initiales :
    F(0)=0
    F(1)=1

    suite:
    F(n)=F(n-1)+F(n-2)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    type1 Fib(type2 n)
    {
       type1 F" = 0;
       type1 F' = 1;
       type1 F = F";
     
       for (int i = 0; i <= n; i++)
       {
          F = F" + F';
          F" = F';
          F' = F;
       }
       return F;
    }

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 155
    Points : 90
    Points
    90
    Par défaut
    Citation Envoyé par capitN.flam
    la première chose que tu peux changer c'est le type de retour etant donné que ce sera toujours un nombre >0 tu peux retourner un unsigned long de plus tu prends en paramètre un unsigned donc...
    Bonne idée, je vais changer ça


    Citation Envoyé par bigboomshakala
    la suite de Fibonacci commence à 0
    Ah, dans mon livre C++ il prétendent que cela commence à 1 ...

    Sinon ils proposent (dans le livre) une méthode en récursif :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int fib(int n)
    {
        if (n < 3) 
           return 1;
        else 
           return (fib(n-2) + fib(n-1));
    }
    Mais il parait qu'elle n'est pas très efficace (ils ne précisent pas pourquoi). Ma fonction est elle plus efficace que celle-ci ? Si oui pourquoi ?

    merci

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 155
    Points : 90
    Points
    90
    Par défaut
    Oh oui. Ma fonction est bien plus rapide que celle utilisant la récursivité, mais je ne compend pas pourquoi ...

    Faut-il en conclure que la récursivité est une méthode à proscrire lorsque c'est possible ?

    merci

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 41
    Points : 45
    Points
    45
    Par défaut
    De mémoire :

    lorsque tu fait une fonction récursive tu l'appel un nombre important de fois, à ce moment là le temps d'appel de la fonction entre en compte devant le temps de calcul.
    Si tu appel 100 fois la même fonction avec 0.01 sec de temps d'appel et 0.1 sec de temps de calcul tu mettra 11 sec au lieu des 10 sec de temps de calcul.
    La récursivité est bien mais pas top niveau performances.

    tu peux faire le même essait avec le calcul de factoriel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    unsigned long fact( int n )
    {
      if( n <= 2 ) return n;
      return n*fact( n-1 );
    }
    ou alors la version plus rapide :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    unsigned long fact( int n )
    {
      unsigned long res = 1;
      for( int i = n; i > 1; --i )
      {
         res *= i;
      }
      return res;
    }
    et là tu devrait voir la différence...

    Tarrke

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 155
    Points : 90
    Points
    90
    Par défaut
    Ah bon, eh bien oui en fait c'est logique.
    Chaque appel de fonction ralentit le programme. Et la récursivité ce n'est pas évident à maîtriser ...

    Bon, conclusion -> vive les boucles for

    merci

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 41
    Points : 45
    Points
    45
    Par défaut
    De rien,

    mais n'oublie pas, la programmation en réccursif est plus facil pour certains, en effet beaucoup de mathématiciens préfèrent un algo récursif car il le comprennent, mais à nous de le dérécursifier si possible.
    Il ne faut pas bannir le récursif pour ses performances, une heure de codage et une heure d'execution valent peut-être meiux que dix heures de codage et 30 minutes d'execution non ?

    Ravis d'avoir pu aider
    Tarrke

  9. #9
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    +1, surtout si on rajoute 5 minutes de maintenance d'un côté, et 5 jours de l'autre

    Pour info, il existe des cas de récursivité qu'un compilateur est à même d'optimiser plus aisément (cherche récursivité terminale pour plus d'info), mais on commence généralement à perdre en clarté et simplicité du code.

    Enfin, en terme de performances, notons qu'il est possible si l'on souhaite calculer la valeur d'un membre dont le rang est connu au moment de la compilation de calculer cette valeur à la compilation elle aussi. Et là, comme pour tout calcul à la compilation, la récursivité est la seule méthode disponible.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 155
    Points : 90
    Points
    90
    Par défaut
    Citation Envoyé par JolyLoic
    comme pour tout calcul à la compilation, la récursivité est la seule méthode disponible
    Ah, ça je ne savais pas tient.
    De toute façon je ne jette pas la récursivité, je suppose que ça me servira bien un jour ...

    merci

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 76
    Points : 61
    Points
    61
    Par défaut
    et puis faire de la récursivité n'empèvhe pas de réfléchir!
    essayez ce programme, deux fonction qui calcule le nième terme de suite de fibonaci:

    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
    #include <iostream>
     
    int string2int(char* s, int p = 0){
      if( *s != '\0' )
        return string2int(s+1, 10*p + *s -'0');
      else return p;
    }
     
    unsigned long fibonaci_recur(unsigned int n){
      if(n<2)return 1;
      else return fibonaci_recur(n-1) + fibonaci_recur(n-2);
    }
     
    unsigned long fibonaci_updated(unsigned int n){
      if(n<2)return 1;
      else {  // n>=2
        int fm2 = fibonaci_updated(n-2), fm3 = 0;
        if(n>2) fm3 = fibonaci_updated(n-3);
        return 2*fm2 + fm3;
      }
    }
     
    using namespace std;
     
    int main(int argc, char* argv[]){
      if(argc<2)cerr << "Il faut un argument !" << endl;
      int n = string2int(argv[1]);
     
      cout << "lancement fonction 1..." << endl;
      cout << "le résultat est : " << fibonaci_recur(n) << endl << endl;
     
      cout << "lancement fonction 2..." << endl;
      cout << "le résultat est : " << fibonaci_updated(n) << endl << endl;
    }
    je ne sais pas comment chronométré alors je ne l'ai pas fait. si quelqu'un veux le faire

    ne pas oublier aussi que le C++ n'est pas spécialement optimiser pour la récursivité, un language tel que le CAML est beaucoup plus efficace dans ce domaine.
    2 n'est pas égal à 3, même pour de grandes valeurs de 2 ou de petites valeurs de 3

  12. #12
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 533
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 533
    Points : 6 709
    Points
    6 709
    Par défaut
    oui C++ n'est pas le meilleur pour gerer les recursions, mais de toute facon une vraie gestion ne peut se faire qu'avec un interpreteur, et des langages que je connais la palme revient à Lisp de ce cote : Vlisp & LeLisp (et mon lisp et logo persos sur Goupil il y a pret de 20 ans !) traitait par exemple les recursions "enveloppé" du type de celle de factorielle en recursif : (* n (fact (- n 1))) qui n'empilait rien car la multiplication etait faite tout de suite et non au retour. Ceci est théoriquement possible à faire avec un langage compile même si ce n'est pas le cas, par contre les cas de recursions croisées (A appelle B qui appelle A etc ..., ou avec plus de fonctions intermediaires) sont plus dure à traiter à la compilation.

    A part cela la récursion permet de faire des codes concis et clairs, ce ne sont pas les tours de hanoi qui vont me contredire
    Bruno Pagès, auteur de Bouml (freeware), mes tutoriels sur DVP (vieux, non à jour )

    N'oubliez pas de consulter les FAQ UML et les cours et tutoriels UML

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 155
    Points : 90
    Points
    90
    Par défaut
    et puis faire de la récursivité n'empèvhe pas de réfléchir!
    Ah ben non, pour moi la récursivité ça oblige à réfléchire

    merci

  14. #14
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Points : 2 757
    Points
    2 757
    Par défaut
    :

    Si oui, mettre le tag pour que tout le monde le sache.
    merci

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

Discussions similaires

  1. Suite de Fibonacci
    Par James de Paris dans le forum Général Python
    Réponses: 3
    Dernier message: 17/10/2009, 00h41
  2. [68k] Problème exercice suite de Fibonacci
    Par tim91700 dans le forum Autres architectures
    Réponses: 15
    Dernier message: 31/03/2009, 20h59
  3. Suite de Fibonacci parallélisée
    Par nicolas66 dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 07/12/2006, 22h04
  4. Réponses: 6
    Dernier message: 01/12/2006, 17h32
  5. [NASM] Problème suite de Fibonacci
    Par empochez dans le forum Assembleur
    Réponses: 1
    Dernier message: 05/04/2006, 11h17

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