为什么这个递归函数返回undefined? [英] Why does this recursive function return undefined?

查看:154
本文介绍了为什么这个递归函数返回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:

  1. 带参数AAABBB,他们的长度不是0,转到其他地方。进入else后, str3 AB,调用 merge(AA, BB)
  2. 带参数AABB,他们的长度不是0,转到其他地方。进入else后, str3 现在ABAB,调用 merge(A, B)
  3. 带参数AB,他们的长度不是0,转到其他地方。一旦进入,否则 str3 现在ABABAB,调用 merge(, )
  4. 使用空字符串参数,长度为0.现在转到if语句,其中记录了 str3 ,并返回。
  5. 由于合并(,)调用已解决(至ABABAB因为它已被退回),我们继续在我们中断的地方通话合并(A,B),从而向上调用堆栈。
  6. 我们在else分支中的调用 merge(A,B)中停止。该调用中没有更多的语句或表达式,因此它已得到解决。 没有返回语句,因此默认情况下它返回 undefined 。我们调高调用堆栈来调用 merge(AA,BB)我们离开的地方。
  7. 我们从离开的地方开始在其他分支中关闭合并(AA,BB)。该调用中没有更多的语句或表达式,因此它已得到解决。同样,没有返回语句,因此默认情况下返回 undefined 。我们调高调用堆栈来调用 merge(AAA,BBB)我们离开的地方。
  8. 我们从电话中断的地方开始code>在else分支中合并(AAA,BBB)。该调用中没有更多的语句或表达式,因此它已得到解决。同样,没有返回语句,因此默认情况下返回 undefined 。没有更多的电话,所以一切都已解决 - 和合并(AAA,BBB)返回 undefined
  1. With arguments "AAA" and "BBB", their lengths are not 0, go to else. Once in else, str3 is "AB", call merge("AA", "BB").
  2. With arguments "AA" and "BB", their lengths are not 0, go to else. Once in else, str3 is now "ABAB", call merge("A", "B").
  3. With arguments "A" and "B", their lengths are not 0, go to else. Once in else, str3 is now "ABABAB", call merge("", "").
  4. With empty string arguments, length is 0. Now go to the if statement, where str3 is logged, and returned.
  5. Since the merge("", "") call has resolved (to "ABABAB" as it is returned), we continue where we left off in the call merge("A", "B"), thus going "up" the call stack.
  6. 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 returns undefined. We go "up" the call stack to call merge("AA", "BB") where we left off.
  7. 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 returns undefined. We go "up" the call stack to call merge("AAA", "BBB") where we left off.
  8. 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 returns undefined. There are no more calls, so everything's resolved - and merge("AAA", "BBB") returns undefined.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆