[英]Need help understanding recursive function to generate all combinations of a string
I came across this code , but am having a hard time figuring out how the flow of this function is working. 我遇到了这段代码 ,但我很难弄清楚这个函数的流程是如何工作的。
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, []);
}
I've console.logged a bunch of statements, but I'm getting lost in the recursion. 我控制台。记录了一堆语句,但我在递归时迷路了。 Specifically, I don't understand what's happening after the first of the two
fn
's gets returned. 具体来说,我不明白在两个
fn
的第一个返回后发生了什么。 It's simply returning a
, but to me, it appears as if the second fn
knows to take the returned a
. 它只是返回
a
,但对我来说,似乎第二个fn
知道fn
了a
。 How does that work? 这是如何运作的? Shouldn't it need a variable assignment like so:
它不应该像这样需要变量赋值:
a = fn(active + rest[0], rest.slice(1), a);
fn(active, rest.slice(1), a);
Well, if you're trying to understand the specific algorithm, the key insight is the a
variable accumulates the result by reference -- the lower level calls to combinations()
push individual elements onto a
and the function eventually returns accumulated result. 好吧,如果你想了解具体的算法,关键洞察力是
a
变量引用积累的结果-下级调用combinations()
推动各个元素到a
与函数最终返回积累的结果。
A good print statement can help understanding cases like this. 一个好的打印声明可以帮助理解这样的情况。 Here's the code with the addition of a print out that shows you what level of recursion you're at.
这是添加了打印输出的代码,显示了您所处的递归级别。 And I renamed
a
to accum
to make it a bit more obvious: 我将
a
重命名为accum
以使其更明显:
function combinations(str) {
var fn = function(active, rest, accum, level) {
console.log(new Array(level).join('--'),
' active: \'' + active + '\'',
'rest: \'' + rest + '\'',
'accum:', accum);
if (!active && !rest)
return;
if (!rest) {
accum.push(active);
} else {
fn(active + rest[0], rest.slice(1), accum, level + 1);
fn(active, rest.slice(1), accum, level + 1);
}
return accum;
}
return fn("", str, [], 1);
}
and the results: 结果:
combinations('abc')
active: '' rest: 'abc' accum: []
-- active: 'a' rest: 'bc' accum: []
---- active: 'ab' rest: 'c' accum: []
------ active: 'abc' rest: '' accum: []
------ active: 'ab' rest: '' accum: [ 'abc' ]
---- active: 'a' rest: 'c' accum: [ 'abc', 'ab' ]
------ active: 'ac' rest: '' accum: [ 'abc', 'ab' ]
------ active: 'a' rest: '' accum: [ 'abc', 'ab', 'ac' ]
-- active: '' rest: 'bc' accum: [ 'abc', 'ab', 'ac', 'a' ]
---- active: 'b' rest: 'c' accum: [ 'abc', 'ab', 'ac', 'a' ]
------ active: 'bc' rest: '' accum: [ 'abc', 'ab', 'ac', 'a' ]
------ active: 'b' rest: '' accum: [ 'abc', 'ab', 'ac', 'a', 'bc' ]
---- active: '' rest: 'c' accum: [ 'abc', 'ab', 'ac', 'a', 'bc', 'b' ]
------ active: 'c' rest: '' accum: [ 'abc', 'ab', 'ac', 'a', 'bc', 'b' ]
------ active: '' rest: '' accum: [ 'abc', 'ab', 'ac', 'a', 'bc', 'b', 'c' ]
[ 'abc', 'ab', 'ac', 'a', 'bc', 'b', 'c' ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.