简体   繁体   English

这个递归组合函数中的“return a”有什么作用?

[英]What does "return a" in this recursive combinations function does?

I went over this function over and over in Chrome debugger and still can't understand what return a does.我在 Chrome 调试器中一遍又一遍地检查了这个函数,但仍然无法理解return a作用。 Thanks for helping me out!谢谢你的协助!

Here's some clarification: I understand the first round.这里有一些澄清:我理解第一轮。 The anonymous function gets called with the following parameters:使用以下参数调用匿名函数:

active = "", rest = "abc", a = []活动 = "", 休息 = "abc", a = []

It then calls itself til rest is empty, when it populates the a array:然后它会调用自己直到rest为空,当它填充a数组时:

active = "abc", rest = "", a = ["abc"]活动 = "abc", 休息 = "", a = ["abc"]

At this point we arrive to return a , and the debugger jumps to the second fn call in the else statement instead of the first if statement.此时我们return a ,调试器跳转到 else 语句中的第二个 fn 调用,而不是第一个 if 语句。 The parameters already look like this:参数已经如下所示:

active = "ab", rest = "c", a = ["abc"]活动 = "ab", 休息 = "c", a = ["abc"]

This is the part I don't understand at all.这是我完全不明白的部分。 I know the recursion is only over when active and rest is empty, but after return a the if statements don't even get checked in the debugger, it just highlights the mentioned second function call, and at that point "c" is already assigned to rest .我知道递归只有在activerest为空时才结束,但是在return a ,if 语句甚至没有在调试器中检查,它只是突出显示了提到的第二个函数调用,此时已经分配了“c” rest I guess the reason why this function doesn't produce duplicates also lies here, but that might be another question if not.我想这个函数不产生重复的原因也在这里,但如果没有,那可能是另一个问题。 Anyway, thanks again for the help!无论如何,再次感谢您的帮助!

combinations("abc");

function combinations(str) {
    var fn = function(active, rest, a) {
        if (!active && !rest)
            return;
        if (!rest) {
            a.push(active);
        } else {
            fn(active + rest[0], rest.slice(1), a);
            fn(active, rest.slice(1), a);
        }
        return a;
    }
    return fn("", str, []);
}

In this case the recursion construct is written oddly and the "return a" is merely to smuggle out the mutated array, the same object initially supplied, back to the helper function so that a direct return can be used on the inner recursive function call.在这种情况下,递归构造的编写很奇怪,“返回 a”只是将最初提供的相同对象的变异数组走私回辅助函数,以便可以在内部递归函数调用中使用直接返回。 (In most contexts, and especially those discussed in recursion primers , recursive functions usually utilize the returned value.) (在大多数情况下,尤其是在递归入门中讨论的情况下,递归函数通常使用返回值。)

Here is a cleaner re-write using the helper function more.这是使用 helper 函数更干净的重写。 I also removed all explicit return statements because they were not adding value here.我还删除了所有明确的 return 语句,因为它们没有在这里增加价值。

function combinations(str) {
    var fn = function(active, rest, a) {
        if (!active && !rest) {
            // base case #1 - implicit return, no recursive call
        } else if (!rest) {
            // base case #2 - implicit return, no recursive call
            a.push(active);
        } else {
            // recursive case, where function is called again
            // (the object "a" is modified in recursion;
            //  result of recursion not directly used)
            fn(active + rest[0], rest.slice(1), a);
            fn(active, rest.slice(1), a);
        }
    }

    var o = [];     // only one output object created..
    fn("", str, o); // ..mutated..
    return o;       // ..and returned to caller.
}

It should then be easy to observe that passing "a" to the recursive function is not needed (ie. it could access "o" in the enclosing scope) because there is no new object assigned to "a" after the initial result array is created.然后应该很容易观察到不需要将“a”传递给递归函数(即它可以访问封闭范围中的“o”),因为在初始结果数组之后没有分配给“a”的新对象创建。

There is a subtle difference in the re-write will (more correctly) return an empty array for an empty input string.重写将(更正确地)为空输入字符串返回一个空数组有一个细微的区别。

While I understand that this question is primarily about how that particular recursive implementation works (and there's already an excellent answer to that!), I think it's worth pointing out that it's an odd implementation, and something like this is probably cleaner:虽然我知道这个问题主要是关于该特定递归实现的工作原理(并且已经有一个很好的答案!),但我认为值得指出的是它是一个奇怪的实现,像这样的东西可能更清晰:

 const combinations = (str, active = '') => str .length == 0 ? active .length == 0 ? [] : [active] : [ ... combinations (str .slice (1), active + str [0]), ... combinations (str .slice (1), active) ] console .log (combinations ('abc'))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM