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 :

Récursivité en c.


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 7
    Par défaut Récursivité en c.
    Bonjour

    Dans une autre discussion de ce forum, j'ai trouvé le code ci-dessous d'une fonction qui détermine le nombre de chiffres d'un entier n passé en argument. Le programme fonctionne bien.

    int nbr_chiffre(int n)
    {
    if(n<10) return 1;

    int result;
    result = 1+nbr_chiffre(n/10);
    return result;
    }


    Je n'arrive pas à voir comment en utilisant la récursivité on peut incrémenter
    la variable result à chaque appel de la fonction et en divisant l'argument par 10.

    Est-ce que quelqu'un peut m'éclairer?

    Merci bien. :

  2. #2
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 16
    Par défaut
    Pour bien comprendre ce bout de code, je n'aurai qu'un conseil a te donner

    prend une feuille de papier et un crayon
    choisi un valeur au hasard genre 1024
    puis tu executes le programme avec ta tete, ta feuille et ton crayon

    et la tu devrais voir le miracle s'accomplir, la recursivite c'est un bete appel de fonction

  3. #3
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 35
    Par défaut
    Le mieux a mon avis en général pour bien voir comment fonctionne un algorithme récursif c'est de le faire tourner à la main avec un cours exemple.

    Prenons n=123 :

    on a successivement :

    nbr_chiffre(123)
    {

    123 > 10 donc tu es dans le deuxieme cas

    tu vas retourner : 1 + la taille de 123/10 <=> 1 + la taille de 12 :


    nbr_chiffre(12)
    {

    12>10 donc deuxieme cas.

    tu vas retourner : 1 + la taille de 12/10 <=> 1 + la taille de 1 :


    nbr_chiffre(1)
    {

    1<10
    donc tu retoune 1;

    }

    nbr_chiffre(12) retourne 1+1;

    }

    nbr_chiffre(123) retourne 1+2;

    }


    (Je suis clair ? parce que c'est pas facile d'explique un algo récursif )

  4. #4
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 7
    Par défaut
    Merci à RAF

    C'est déjà beaucoup plus clair et j'ai ...presque tout compris ()
    Juste un point encore un peu obscur:

    tu vas retourner : 1 + la taille de 12/10 <=> 1 + la taille de 1 :

    Comment la fonction "connaît elle" la taille de 1 qu'elle va retourner après le dernier appel?
    C'est peut être tout simple à voir mais c'est précisement ce qui me pose problème.

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    En fait, ça, c'est comme la factorielle: C'est une chose tellement facile à faire en itératif que c'est bête de la faire en récursif.
    L'utilité de la récursivité apparait plus évidente pour des fonctions comme le parcours d'arbres.

    Note: Tu liras aussi parfois le terme "récursivité terminale", qui consiste à des appels récursifs dont le résultat est directement passé à return, sans aucun autre calcul. Ces fonctions sont particulières, car elles peuvent être optimisées par le compilateur pour supprimer la récursivité.

    La fonction nbr_chiffre() n'a pas une récursivité terminale, puisqu'on fait une opération sur le résultat (une addition).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    tu vas retourner : 1 + la taille de 12/10 <=> 1 + la taille de 1 :

    Comment la fonction "connaît elle" la taille de 1 qu'elle va retourner après le dernier appel?
    Parce que 1 est inférieur à 10.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 35
    Par défaut
    Oui c'est ce que j'ai apellé le premier cas,

    Heu je sais plus comment ça s'appelle ? la condition d'arrêt de la récursivité ?

    Ici ta condition c'est que dés que tu passe un nombre inférieur a 10, tu connais sa taille, soit 1, donc tu peut la retourner directement.

    De même, si tu sais que tu vas toujours passer des nombres >=10, tu aurais put mettre comme condition d'arrêt :

    if (n<100) return 2;

    Jte conseilles vraiment de le faire tourner à la main sur papier! En écrivant bien tes appels de fonction.

  8. #8
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 7
    Par défaut
    OK!

    j'ai posté mon derniers message avant de prendre connaissance de ta réponse.
    C'est en fait ce point que "j'oubliais" de prendre encompte:

    Ici ta condition c'est que dés que tu passe un nombre inférieur a 10, tu connais sa taille, soit 1, donc tu peut la retourner directement.


    C'est clair maintenant.

    Merci à RAF et à tous ceux qui ont bien voulu me répondre.

  9. #9
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 7
    Par défaut
    Merci pour vos réponses et votre aide.

    D'accord, ici on peut largement utiliser et de manière plus simple l'itération.
    En fait mon objectif est de d'essayer de comprendre le mécanisme de la récursivité sur des exemples simples.

    Citation Envoyé par Médinoc Voir le message
    Parce que 1 est inférieur à 10.
    Hélas je ne vois toujours pas pourquoi résult est inréménté de 1 lors de chaque appel.

  10. #10
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    En fait, ça, c'est comme la factorielle: C'est une chose tellement facile à faire en itératif que c'est bête de la faire en récursif.
    L'utilité de la récursivité apparait plus évidente pour des fonctions comme le parcours d'arbres.

    Note: Tu liras aussi parfois le terme "récursivité terminale", qui consiste à des appels récursifs dont le résultat est directement passé à return, sans aucun autre calcul. Ces fonctions sont particulières, car elles peuvent être optimisées par le compilateur pour supprimer la récursivité.

    La fonction nbr_chiffre() n'a pas une récursivité terminale, puisqu'on fait une opération sur le résultat (une addition).
    Voici une version récursive terminale (qui se traduit facilement en une version itérative. D'ailleurs, mon gcc 4.1.3 le fait tout seul avec l'option -O2):

    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
    #include <stdio.h>
     
    int nbr_chiffres_rec(int n, int resultat)
    {
        if (n < 10)
        {
            return resultat + 1;
        }
        else
        {
            return nbr_chiffres_rec(n/10, resultat + 1);
        }
    }
     
    int nbr_chiffres(int n)
    {
        if (n < 0)
        {
            n = (-1) * n;
        }
        return nbr_chiffres_rec(n, 0);
    }
     
     
    int main(void)
    {
        int nchiffres;
        nchiffres = nbr_chiffres(10);
        printf("n = %d\n", nchiffres);
     
        return 0;
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

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

Discussions similaires

  1. Cours : algorithmes et récursivité
    Par Community Management dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 17/10/2018, 00h38
  2. [Système] Récursivité et itération
    Par Floréal dans le forum Langage
    Réponses: 8
    Dernier message: 19/04/2005, 14h57
  3. Parcours d'arbre sans récursivité
    Par Morvan Mikael dans le forum Algorithmes et structures de données
    Réponses: 12
    Dernier message: 12/04/2005, 13h57
  4. [PS] Récursivité !
    Par maitrebn dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 01/10/2004, 12h18
  5. récursivité
    Par krimson dans le forum PostgreSQL
    Réponses: 12
    Dernier message: 06/05/2004, 15h54

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