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

Contribuez Discussion :

[FAQ][Algo] - Récursivité


Sujet :

Contribuez

  1. #1
    Membre averti Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Points : 369
    Points
    369
    Par défaut [FAQ][Algo] - Récursivité
    Voici un petit mot sur la récursivité qui pourrait être pratique autant dans une FAQ traitant les algos.

    Je ne sais pas si le sujet est déjà abordé dans une autre FAQ mais bon, ca ne coûte pas grand chose de contribuer de toute façon!


    Qu'est-ce que la récursivité?
    La récursivité est le principe selon lequel une fonction s'appelle elle-même, en boucle, jusqu'à ce qu'une (ou plusieurs) conditions d'arrêt soient respectées.

    Elle repose principalement sur les 3 points suivant
    1. L'expression récursive (auto-appeler la fonction)
    2. La condition d'arrêt (quand arrête-t-on de boucler?)
    3. La convergence (ce qui nous amène vers la condition d'arrêt)



    Voici un exemple simplet et concret.

    Supposons que l'on veut calculer le factorielle d'un nombre positif n (par exemple: le factoriel de 6 est 6*5*4*3*2*1 = 720).

    La fonction récursive pourrait ressembler à quelque chose du genre, dans une notation C:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    long factorielle(unsigned int n)
    {
       if (n == 1 || n == 0) return 1l;
       return ((long) n * factoriel(n-1));
    }
    La condition d'arrêt dans l'exemple ci-haut est (n == 1 OU n == 0)
    L'expression récursive est le deuxième return, soit return (n * factoriel(n-1));
    La convergence est donc intégré à l'expression récursive dans ce cas-ci (et c'est souvent le cas)
    Ainsi, on bouclera les appels à factorielle(int) jusqu'à temps que le nombre passé en paramètre soit 1.

    Voila une façon simple et efficace de calculer le factorielle d'un nombre positif en utilisant la récursivité. Imaginez maintenant tout ce que l'on peut faire avec la récursivité



    J'espère que ca sera utile à quelqu'un!


    EDIT: FAQ algos et non C/C++

  2. #2
    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 : 47
    Localisation : Suisse

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Bonjour,

    Une FAQ est en train de se créer sur le forum Algorithmique, et je me demande si elle ne serait pas plus adaptée pour héberger une Q/R sur la récursivité. En effet, je pense qu'il s'agit là d'une technique qui n'est pas propre ni au langage C ni à C++, mais dont la portée peut être étendu à n'importe quel langage structuré.

    En tout cas, je verrais bien une Q/R sur la récursivité, en pseudo-code sur la FAQ d'algo.

    Meilleures salutations

    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++

    +

  3. #3
    Membre averti Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Points : 369
    Points
    369
    Par défaut
    C'est également ce que je me suis dit après y avoir repenser. C'est plus un concept que quelque chose de relié directement à un langage.

    Alors pour la FAQ Algo alors!

  4. #4
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Yop, voilà, je ne savais pas si ça allait être déplacé ou si tu allais reposter.

    J'avais des petites remarques.

    - Notation C (et non algorithmique), enfin, tu n'as peut être pas encore eu le tps de changer

    - Même en C, le cast est assez mal placé (même si ça marche), fact renvoit un long, donc return (long) (n * factoriel(n-1)); devrait plutôt être return ((long)n * factoriel(n-1)); vu qu'il y a une multiplication par n.

    - La condition if (n < 0) exit(1); est inutile, il suffit de prendre en entrée un unsigned int (ou spécifier en algorithmique une précondition à l'appel, c'est à dire n : Entier positif)

    - C'est factorielle et non pas factoriel


    Peut-être faire une description des fonctions récursives terminales et non terminales.

    Peut-être préciser (enfin, là, ce n'est plus de l'algo) que certains langages ne se pretent pas bien aux appels récursifs. Par exemple le C/C++, car ils mettent les valeurs des appels de fonctions sur la pile, et il peut vite y avoir des débordements de piles si c'est mal fait. De plus, je ne suis pas sûr que le langage C utilise les propriétés de récursivité terminal ou non.
    Je ne répondrai à aucune question technique en privé

  5. #5
    Membre averti Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Points : 369
    Points
    369
    Par défaut
    Merci de ton avis millie, je vais essayer de corriger cela et reposter.

  6. #6
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Citation Envoyé par millie
    Peut-être préciser (enfin, là, ce n'est plus de l'algo) que certains langages ne se pretent pas bien aux appels récursifs. Par exemple le C/C++, car ils mettent les valeurs des appels de fonctions sur la pile, et il peut vite y avoir des débordements de piles si c'est mal fait. De plus, je ne suis pas sûr que le langage C utilise les propriétés de récursivité terminal ou non.
    Les compilateurs C/C++ récents détectent les cas de récursivité terminale il me semble.

  7. #7
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par HanLee
    Les compilateurs C/C++ récents détectent les cas de récursivité terminale il me semble.
    Oui, je ne suis pas sûr non plus. Par contre, je suis sûr qu'il met les arguments des fonctions sur la pile, donc c'est pas très bon si il y a beaucoup d'appel.
    Je ne répondrai à aucune question technique en privé

  8. #8
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par HanLee
    Les compilateurs C/C++ récents détectent les cas de récursivité terminale il me semble.
    Dès qu'on utilise des destructeurs en C++, les cas de récursivité terminale se font rares.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  9. #9
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par millie
    Oui, je ne suis pas sûr non plus. Par contre, je suis sûr qu'il met les arguments des fonctions sur la pile, donc c'est pas très bon si il y a beaucoup d'appel.
    Les compilateurs qui implémentent la suppression des appels terminaux (qu'ils soient récursifs ou non -- on peut faire la même chose dès que l'appel est la dernière chose faite dans la fonction, ajuster la pile peut être plus délicat si le nombre de paramètres est différents) remplacent les appels finaux par des modifications de leurs paramètres et un saut.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  10. #10
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Citation Envoyé par millie
    Par contre, je suis sûr qu'il met les arguments des fonctions sur la pile, donc c'est pas très bon si il y a beaucoup d'appel.
    Citation Envoyé par Jean-Marc.Bourguet
    Les compilateurs qui implémentent la suppression des appels terminaux ...
    Comme l'a dis Jean-Marc, les cas terminaux ne sont pas tous gérés de la même façon. Il faut donc savoir comment fonctionne son compilateur avant de conclure.

  11. #11
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Dès qu'on utilise des destructeurs en C++, les cas de récursivité terminale se font rares.
    T'as pas des exemples ? J'vois pas trop ce que tu voulais dire.

  12. #12
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par HanLee
    T'as pas des exemples ? J'vois pas trop ce que tu voulais dire.
    Le destructeur des variables automatiques d'exécutant à la sortie des fonctions après tout le code de la fonction, l'appel récursif à la fonction peut difficilement être terminal: les destructeurs doivent s'exécuter après.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

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