Vous avez une fonction récursive qui peut se résumer comme ceci:
recursive(i, j):
if stopping condition:
return value
loop:
if test current value involving recursive call passes:
set value based on recursive call
return value # this appears to be missing from your example
(je vais être assez lâche avec le code pseudo il re, pour souligner la structure du code plutôt que la mise en œuvre spécifique)
Et vous voulez l'aplatir à une approche purement itérative. Tout d'abord, il serait bon de décrire exactement ce que cela implique dans le cas général, car vous semblez être intéressé par cela. Ensuite, nous pouvons passer à l'aplatissement du pseudo-code ci-dessus.
Maintenant aplatir une fonction récursive primitive est assez simple. Lorsque vous le code donné qui ressemble à:
simple(i):
if i has reached the limit: # stopping condition
return value
# body of method here
return simple(i + 1) # recursive call
Vous pouvez voir rapidement que les appels récursifs continueront jusqu'à ce que i
atteint la limite prédéfinie. Lorsque cela se produit, le value
sera retourné. La forme itérative de ceci est:
simple_iterative(start):
for (i = start; i < limit; i++):
# body here
return value
Cela fonctionne parce que les appels récursifs forment l'arbre d'appel suivant:
simple(1)
-> simple(2)
-> simple(3)
...
-> simple(N):
return value
Je décrirais cet arbre d'appel comme un morceau de ficelle. Il a un début, un milieu et une fin. Les différents appels se produisent à différents points de la chaîne. Une chaîne d'appels de ce type ressemble beaucoup à une boucle for - tout le travail effectué par la fonction est passé à l'invocation suivante et le résultat final de la récursivité est simplement renvoyé. La version for loop prend juste les valeurs qui seraient passées dans les différents appels et exécute le code du corps sur eux.
Simple jusqu'ici!
Maintenant, votre méthode est plus complexe de deux façons:
- Il y a plusieurs états distincts qui font des appels récursifs
- Ces états sont eux-mêmes dans une boucle
donc votre arbre d'appel est quelque chose comme:
recursive(i, j):
for (v in 1, 2, ... N):
-> first_recursive_call(i + v, j):
-> ... inner calls ...
-> potential second recursive call(i + v, j):
-> ... inner calls ...
Comme vous pouvez le voir s pas du tout comme une chaîne. Au lieu de cela, c'est vraiment comme un arbre (ou un buisson) en ce que chaque appel entraîne deux autres appels. À ce stade, il est vraiment très difficile de revenir à une fonction entièrement itérative.
Ceci est dû à la relation fondamentale entre les boucles et la récursivité. Toute boucle peut être réaffirmée comme un appel récursif. Cependant, tous les appels récursifs ne peuvent pas être transformés en boucles.
La classe d'appels récursifs qui peuvent être transformés en boucles est appelée primitive récursion. Votre fonction semble initialement avoir transcendé cela. Si tel est le cas, vous ne pourrez pas le transformer en une fonction purement itérative (à moins d'implémenter une pile d'appels et similaire dans votre fonction).
Cette vidéo explique la différence entre récursion primitive et types fondamentalement récursifs qui suivent:
https://www.youtube.com/watch?v=i7sm9dzFtEI
Je voudrais ajouter que votre condition et la valeur que vous attribuez à max
semblent être les mêmes. Si tel est le cas, vous pouvez supprimer l'un des appels récursifs, ce qui permet à votre fonction de devenir une instance de récursivité primitive enveloppée dans une boucle. Si vous l'avez fait, vous pourrez peut-être l'aplatir.
Je ne vois pas le problème non plus. – AppliedNumbers