Je tente d'écrire une fonction qui combine deux chaînes en utilisant la récursivité. Mon code est ci-dessous, mais je ne sais pas pourquoi la fonction retourne indéfinie surtout lorsque je console.log dans le boîtier de base et qu'il n'imprime pas défini, mais plutôt la valeur correcte.
var str3="" function merge(str1,str2){ if(str1.length==0||str2.length==0){ console.log(str3) return str3; } else{ str3=str3+str1.substring(0,1)+str2.substring(0,1); merge(str1.substring(1,str1.length),str2.substring(1,str2.length)) } } merge("AAA","BBB") //--> returns undefined but the console.log(str3) gives correct answer
Explication
Le problème est que vous ne renvoyez pas le résultat de l'appel récursif, donc il est indéfini lorsque l'appel complet à merge
est résolu.
Permettez-moi de vous faire passer par l'exécution, étape par étape:
"AAA"
et "BBB"
, leurs longueurs ne sont pas 0, aller à autre chose. Une fois, str3
est "AB"
, merge("AA", "BB")
appel merge("AA", "BB")
. "AA"
et "BB"
, leurs longueurs ne sont pas 0, aller plus loin. Une fois, str3
est maintenant "ABAB"
, merge("A", "B")
appel merge("A", "B")
. "A"
et "B"
, leurs longueurs ne sont pas 0, aller plus loin. Une fois, str3
est maintenant "ABABAB"
, merge("", "")
appels merge("", "")
. str3
est enregistré et renvoyé. merge("", "")
a résolu (pour "ABABAB"
tel qu'il est renvoyé), nous continuons là où nous l'avons laissé dans la merge("A", "B")
appel merge("A", "B")
, donc "haut" le Pile d'appel. merge("A", "B")
appels merge("A", "B")
, dans la branche else. Il n'y a plus de déclarations ou d'expressions dans cet appel, donc c'est résolu. Il n'y a pas de déclaration, donc, par défaut, il renvoie undefined
. Nous allons "haut" la pile d'appel pour appeler merge("AA", "BB")
où nous avons laissé. merge("AA", "BB")
appel merge("AA", "BB")
, dans la branche else. Il n'y a plus de déclarations ou d'expressions dans cet appel, donc c'est résolu. Encore une fois, il n'y a pas de déclarations de retour, par défaut, il renvoie undefined
. Nous allons "haut" la pile d'appel pour appeler merge("AAA", "BBB")
où nous avons laissé. merge("AAA", "BBB")
appels merge("AAA", "BBB")
, dans la branche else. Il n'y a plus de déclarations ou d'expressions dans cet appel, donc c'est résolu. Encore une fois, il n'y a pas de déclarations de retour, par défaut, il renvoie undefined
. Il n'y a plus d'appels, donc tout est résolu – et merge("AAA", "BBB")
renvoie undefined
. TL; DR: l'appel récursif n'est pas retourné sur chaque appel dans la branche else, de sorte que la valeur de str3
est retournée à la merge("A", "B")
appel merge("A", "B")
. La merge("A", "B")
appel merge("A", "B")
ne renvoie rien, elle revient undefined
. Il en va de même pour tous les autres appels – ils n'ont pas de déclaration dans la branche else, si undefined
est renvoyé. Lorsque tous les appels sont résolus, undefined
est renvoyé.
Solution
La solution consiste simplement à préciser le return
à vos appels récursifs. De cette façon, le résultat de chaque appel serait renvoyé, 'déléguant' la valeur finale retournée de str3
jusqu'à la pile d'appel – l'appel renvoie "ABABAB"
, non undefined
.
Puisque nous renvoyons le résultat de l'appel, les étapes 6, 7 et 8 ci-dessus ont maintenant une déclaration . Cela signifie que nous ne retournons pas undefined
, mais plutôt str3
. C'est parce que la merge("", "")
renvoyé "ABABAB"
, qui est la valeur de str3
. Ce résultat est ensuite renvoyé dans la merge("A", "B")
appel merge("A", "B")
raison de la nouvelle déclaration de return
ajoutée, puis retournée dans la merge("AA", "BB")
appels merge("AA", "BB")
, etc., jusqu'à ce que l'appel soit str3
résolu, et le retourne la valeur de str3
.
Voici le nouveau code:
var str3 = ""; function merge(str1, str2) { if(str1.length == 0 || str2.length == 0) { console.log(str3); return str3; } else { str3 = str3 + str1.substring(0, 1) + str2.substring(0, 1); return merge(str1.substring(1, str1.length), str2.substring(1, str2.length)); //we return the recursive call } } var mergedString = merge("AAA","BBB"); //mergedString is "ABABAB"
Comment vous pouvez voir dans ce guide vous devez return
la fonction récursive:
var str3="" function merge(str1,str2){ if(str1.length==0||str2.length==0){ console.log(str3) return str3; } else{ str3=str3+str1.substring(0,1)+str2.substring(0,1); return merge(str1.substring(1,str1.length),str2.substring(1,str2.length)) } } merge("AAA","BBB")