为什么这个递归函数返回undefined? [英] Why does this recursive function return undefined?
问题描述
我正在尝试编写一个使用递归组合两个字符串的函数。我的代码在下面,但我不知道为什么函数返回undefined,特别是当我在基本情况下的console.log并且它不打印undefined而是正确的值。
I'm attempting to write a function that combines two strings using recursion. My code is below but I don't know why the function returns undefined especially when I console.log within the base case and it does not print undefined but instead the correct value.
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
推荐答案
解释
问题是你没有返回递归调用的结果,因此当整个调用<$时它是未定义的c $ c> merge 已解决。
The problem is that you don't return the recursive call's result, thus it is undefined when the whole call to merge
is resolved.
让我一步一步地指导您完成执行:
Let me take you through the execution, step-by-step:
- 带参数
AAA
和BBB
,他们的长度不是0,转到其他地方。进入else后,str3
为AB
,调用merge(AA, BB)
。 - 带参数
AA
和BB
,他们的长度不是0,转到其他地方。进入else后,str3
现在ABAB
,调用merge(A, B)
。 - 带参数
A
和B
,他们的长度不是0,转到其他地方。一旦进入,否则str3
现在ABABAB
,调用merge(, )
。 - 使用空字符串参数,长度为0.现在转到if语句,其中记录了
str3
,并返回。 - 由于
合并(,)
调用已解决(至ABABAB
因为它已被退回),我们继续在我们中断的地方通话合并(A,B)
,从而向上调用堆栈。 - 我们在else分支中的调用
merge(A,B)
中停止。该调用中没有更多的语句或表达式,因此它已得到解决。 没有返回语句,因此默认情况下它返回undefined
。我们调高调用堆栈来调用merge(AA,BB)
我们离开的地方。 - 我们从离开的地方开始在其他分支中关闭
合并(AA,BB)
。该调用中没有更多的语句或表达式,因此它已得到解决。同样,没有返回语句,因此默认情况下返回undefined
。我们调高调用堆栈来调用merge(AAA,BBB)
我们离开的地方。 - 我们从电话中断的地方开始code>在else分支中合并(AAA,BBB)。该调用中没有更多的语句或表达式,因此它已得到解决。同样,没有返回语句,因此默认情况下返回
undefined
。没有更多的电话,所以一切都已解决 - 和合并(AAA,BBB)
返回undefined
。
- With arguments
"AAA"
and"BBB"
, their lengths are not 0, go to else. Once in else,str3
is"AB"
, callmerge("AA", "BB")
. - With arguments
"AA"
and"BB"
, their lengths are not 0, go to else. Once in else,str3
is now"ABAB"
, callmerge("A", "B")
. - With arguments
"A"
and"B"
, their lengths are not 0, go to else. Once in else,str3
is now"ABABAB"
, callmerge("", "")
. - With empty string arguments, length is 0. Now go to the if statement, where
str3
is logged, and returned. - Since the
merge("", "")
call has resolved (to"ABABAB"
as it is returned), we continue where we left off in the callmerge("A", "B")
, thus going "up" the call stack. - We start where we left off in call
merge("A", "B")
, in the else branch. There are no more statements or expressions in that call, so it's resolved. There are no return statements, so by default it returnsundefined
. We go "up" the call stack to callmerge("AA", "BB")
where we left off. - We start where we left off in call
merge("AA", "BB")
, in the else branch. There are no more statements or expressions in that call, so it's resolved. Again, there are no return statements so by default it returnsundefined
. We go "up" the call stack to callmerge("AAA", "BBB")
where we left off. - We start where we left off in call
merge("AAA", "BBB")
, in the else branch. There are no more statements or expressions in that call, so it's resolved. Again, there are no return statements so by default it returnsundefined
. There are no more calls, so everything's resolved - andmerge("AAA", "BBB")
returnsundefined
.
TL; DR:在else分支的每次调用中都不会返回递归调用,因此值 str3
返回到调用 merge(A,B)
。调用 merge(A,B)
不返回任何内容,返回 undefined
。所有其他调用也是如此 - 它们在else分支中没有return语句,因此返回 undefined
。解决所有通话后,将返回 undefined
。
TL;DR: The recursive call is not returned on each call in the else branch, so the value of str3
is returned to the call merge("A", "B")
. The call merge("A", "B")
does not return anything, it returns undefined
. The same goes for all other calls - they have no return statement in the else branch so undefined
is returned. When all calls are resolved, undefined
is returned.
解决方案
解决方案是简单地将返回
添加到递归调用中。这样,每次调用的结果都将被返回,委托 str3
的最终返回值向上调用堆栈 - 调用返回ABABAB
,而不是未定义
。
The solution is to simply prepend return
to your recursive calls. That way, the result of each call would be returned, 'delegating' the final returned value of str3
up the call stack - the call returns "ABABAB"
, not undefined
.
因为我们现在返回调用的结果,上面的步骤6,7和8现在有一个返回语句。这意味着我们不会返回 undefined
,而是返回 str3
。这是因为 merge(,)
返回ABABAB
,这是<$ c的值$ C> STR3 。然后在调用 merge(A,B)
中返回该结果,因为新添加了 return
语句,然后在调用 merge(AA,BB)
中返回,依此类推,直到调用完全解决,并返回值 str3
。
Since we now return the result of the call, steps 6, 7, and 8 above now have a return statement. That means we don't return undefined
, but instead str3
. This is because merge("", "")
returned "ABABAB"
, which is the value of str3
. That result is then returned in call merge("A", "B")
because of the new added return
statement, which is then returned in call merge("AA", "BB")
, and so on, until the call is completely resolved, and the returns the value of str3
.
这是新代码:
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"
之前, mergedString
将收到 undefined
的值。由于我们现在返回递归调用,因此返回所有内容,因此返回 str3
的值,存储到变量 mergeString
。
Before, mergedString
would have received the value undefined
. Since we now return the recursive calls, everything returned accordingly thus the value of str3
is returned, being stored into variable mergeString
.
这篇关于为什么这个递归函数返回undefined?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!