Voila je suis entrain de réviser l'algo et j'ai trouver un problème dans la derecurssivation j'ai chercher sur developpez.com et j'ai pas trouvée grande choses
Ou puis je trouver des exo ou du cours sur la derecurcivité
et merci ;)
Version imprimable
Voila je suis entrain de réviser l'algo et j'ai trouver un problème dans la derecurssivation j'ai chercher sur developpez.com et j'ai pas trouvée grande choses
Ou puis je trouver des exo ou du cours sur la derecurcivité
et merci ;)
Je ne sais pas si celà peut t'aider, mais en général, pour dérécursiver, on utilise une pile.
ou un while avec a l'interieur des conditions se modifiant a chaque tour...
Pour bien comprendre la récursion, cliquer ici. ;)
c'est quoi la dérecurcivation 8O ? ça a un rapport avec la récursion terminale ?
comme je disais, a mon avis, sans passer jusqu'a des complications de heap, stack, et autres :P, juste des boucles avec reaffectations de variables et re-iterations....
puisque tout algo recursif peut se remplacer (ou remplacer) des series de boucles imbriquees...
Tu as dû être mal renseigné, dans sa forme la plus générale la récursion doit être simulé avec une pile, tout algorithme récursif ne peut pas être traduit en itératif aussi simplement qu'une récursion terminale. (ou alors tu veux dire des boucles imbriquées générés dynamiquement, mais c'est équivalent)
Bien sûr la récursion terminale est le cas trivial, aujourd'hui optimisé par pratiquement tous les compilateurs dignes de ce nom, il y a des cas plus complexes et plus intéressants.
--
Jedaï
je ne sais pas, mais la question posée par le PO m'apparaissait directement faire appel à "comment transformer une récursivité en non-récursif"..
Et, je suis pas vos subtilités sur terminal ou non, mais comme je le dit, des boucles imbriquées dont les indices varient dynamiquement me semblent , pou les cas que j'ai vu, être équivalentes... A la complexité près..
Mais si le but est de "dé-récursiver", ça me semble être l'approche par défaut à avoir, non ??
C'est effectivement, je pense, ce qu'il veut faire. En revanche, pour remplacer des appels récursif, il faut, dans le cas général, remplacer la pile d'appel des fonctions par une autre structure de pile gérée "à la main" dans les boucles. Par exemples, si tu fais un parcours en profondeurs dans un arbre, s'il n'y a pas de lien d'un fils vers son père, il faudra à tout moment garder la pile des noeuds déjà visité pour pouvoir remonter dans l'arbre.
Et une récursion est dite terminale lorsque le résultat de l'appel récursif est directement renvoyé, sans être utilisé dans la fonction.
Par exemple
n'est pas récursif terminal car le résultat est réutilisé pour la multiplication alors queCode:
1
2
3 let rec fact n = if n = 0 then 1 else n*fact (n-1)
(appelle de la forme fact_bis n 1 pour calculer n!) est récursif terminal car on retourne directement le résultat de l'appel.Code:
1
2
3 let rec fact_bis n acc = if n = 0 then acc else fact_bis (n-1) (n*acc)
Un fonction récursive terminale est directement traduisible en une simple boucle, pas une récursive non-terminale.
Il faut voir que, dans le cas général, on ne peut pas rendre une fonction récursive non terminale terminale sans utiliser une structure de pile ad hoc.
je dois être un peu "épais", comme on dit ici, mais je vois pas de différence fondamentale entre les 2.... 8O
Par contre, je suis d'accord avec ce que tu disais au dessus, sauf que pour moi ce ne serait pas une pile mais un simple tableau....
Et donc totalement faisable (quoique compliqué) en boucles....
Si il n'y a pas de liens du fils vers le pere, il y en a quand meme du pere vers le fils....
Cherche quelque chose sur la récursivité terminal sur le web alors :-)
Non, tu ne peux pas avoir un simple tableau car tu n'as aucune idée a priori du nombre d'appel que tu auras à faire, donc de la taille de ton tableau (après, si tu as un tableau de taille dynamique, c'est... une pile :-))Citation:
Par contre, je suis d'accord avec ce que tu disais au dessus, sauf que pour moi ce ne serait pas une pile mais un simple tableau....
Euh... oui, sinon on aurait un peu de mal à parcourir l'arbre hein... mais je ne vois pas le rapport en l'occurenceCitation:
Si il n'y a pas de liens du fils vers le pere, il y en a quand meme du pere vers le fils....
En réalité un tableau de taille dynamique est un moyen de simuler une pile, mais c'est plus "complexe". En ce qui concerne la suppression des appels récursif, une structure de pile (disons en gros comme un tableau de taille dynamique dans lequel on accède qu'au dernier élément ajouté) est suffisante
Je vois plusieurs methodes. Celles deja citees:
- la recursivite terminale est strictement equivalente a une boucle
- l'introduction d'accumulateur (la variable acc dans l'exemple d'alex_pi) permet de modifier certaines recursivites non terminales en recursivites terminales sous certaines hypotheses (associativite de l'operation faite -- notez que les multiplications sont faites dans un ordre different dans l'exemple d'alex_pi) ou avec des transformations additionnelles (essayer de remplacer la multiplication par une soustraction dans la factorielle et refaite l'exercice). Apres on revient au cas precedent.
- l'introduction de piles gerees explicitement
Et plus complexe et plus ad hoc: certains algorithmes peuvent etre modifies pour remplacer la pile par des modifications sur les donnees utilisees. Chercher par exemple comment un GC peut parcourir un graphe sans avoir besoin de place supplementaire.