为什么此递归函数返回未定义?

暗祖

我试图编写一个使用递归结合两个字符串的函数。我的代码在下面,但我不知道该函数为什么返回未定义,尤其是当我在基本情况下使用console.log时,它不会显示未定义而是正确的值。

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
李安德

说明

问题在于您不返回递归调用的结果,因此在merge解决了对整个调用的过程时,它是不确定的

让我一步一步地指导您执行:

  1. 如果参数"AAA""BBB"的长度不为0,则转到其他。一旦别的,str3"AB",电话merge("AA", "BB")
  2. 如果参数"AA""BB"的长度不为0,则转到其他。一旦别人,str3现在"ABAB",通话merge("A", "B")
  3. 如果参数"A""B"的长度不为0,则转到其他。一旦别人,str3现在"ABABAB",通话merge("", "")
  4. 如果使用空字符串参数,则length为0。现在转到if语句,在此处str3记录并返回。
  5. 由于merge("", "")调用已解决("ABABAB"返回原样),因此我们继续在调用中停下来的位置进行操作merge("A", "B"),从而使调用堆栈“上移”。
  6. 我们从merge("A", "B")else分支的call处停下来的地方开始。该调用中没有更多的语句或表达式,因此已解决。没有return语句,因此默认情况下它返回undefined我们“向上”调用堆栈以调用merge("AA", "BB")我们上次中断的地方。
  7. 我们从merge("AA", "BB")else分支的call处停下来的地方开始。该调用中没有更多的语句或表达式,因此已解决。同样,没有return语句,因此默认情况下它返回undefined我们“向上”调用堆栈以调用merge("AAA", "BBB")我们上次中断的地方。
  8. 我们从merge("AAA", "BBB")else分支的call处停下来的地方开始。该调用中没有更多的语句或表达式,因此已解决。同样,没有return语句,因此默认情况下它返回undefined没有更多的电话了,所以一切都解决了,然后merge("AAA", "BBB")返回undefined

TL; DR:递归调用不会在else分支的每个调用上返回,因此的值将str3返回给该调用merge("A", "B")该调用merge("A", "B")不返回任何内容,它返回undefined其他所有调用也是如此-它们在else分支中没有return语句,因此undefined被返回。所有呼叫解决后,undefined将返回。


解决方案是简单地return进行递归调用。这样,将返回每个调用的结果,并“委托”str3向上调用栈的最终返回值-调用返回"ABABAB"not undefined

由于我们现在返回调用结果,因此上面的步骤6、7和8现在具有return语句那意味着我们不返回undefined,而是返回str3这是因为merge("", "")返回了"ABABAB",这是的值str3merge("A", "B")由于添加了新return语句,该结果随后在调用中返回,然后在调用中返回语句,merge("AA", "BB")依此类推,直到完全解决了调用,并返回的值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存储在variable中mergeString

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章