Javascript 所有字谜-递归
我试图理解下面的递归函数来自学递归。我试图解释它低于预期输出和函数本身。我错过了什么?我没有看到从“abc”到“acb”的过程。我试图理解它让我从“abc”变成了“bac”Javascript 所有字谜-递归,javascript,recursion,Javascript,Recursion,我试图理解下面的递归函数来自学递归。我试图解释它低于预期输出和函数本身。我错过了什么?我没有看到从“abc”到“acb”的过程。我试图理解它让我从“abc”变成了“bac” example usage: var anagrams = allAnagrams('abc'); console.log(anagrams); // [ 'abc', 'acb', 'bac', 'bca', 'cab', 'cba' ] var allAn
example usage:
var anagrams = allAnagrams('abc');
console.log(anagrams); // [ 'abc', 'acb', 'bac', 'bca', 'cab', 'cba' ]
var allAnagrams = function(string) {
var uniqueOutput = {};
(function anagram(ana, str) {
// could have also written this as: if(!str)....
if (str === '') {
uniqueOutput[ana] = 1;
}
//recursive call for the length of the anagram.
for (var i = 0; i < str.length; i++) {
anagram(ana + str[i], str.slice(0, i) + str.slice(i + 1));
console.log(ana);
}
})('', string);
console.log(uniqueOutput)
return Object.keys(uniqueOutput);
};
// you are calling the recursive function like this: anagram([anagram=]'', [string=]'abc')
// so the base case is not met on the first iteration since the string isn't empty
// first iteration: i = 0
// anagram('' + 'a' + 'bc' [from str.slice(0 +1)]) ---> resolves to "abc") ---> anagram("abc")
//second iteration: i = 1. we are still in the original call from line 37.
// here below, does "ana" stay as '' since we are still inside the initial recursion call?
//anagram('' + b + a + c) ---- resolves to "bac" ---> anagram("bac")
//third and last iteration iteration: i = 2
//anagram(" " + c + c) ----> anagram("cc") ? not a valid result.
根据您的上述评论:
// first iteration: i = 0
// anagram('' + 'a' + 'bc' [from str.slice(0 +1)]) ---> resolves to "abc") --->
实际上,在i=0
上,传递给anagram
的参数是:
anagram('' + 'a', '' + 'bc');
评估结果如下:
anagram('a', 'bc');
然后在对字谜的调用中,我们再次循环str
,它现在只是“bc”。这将导致另外两个调用anagram
,这将是
anagram('a' + 'b', '' + 'c'); // i = 0
anagram('a' + 'c', 'b' + ''); // i = 1
评估结果如下:
anagram('ab', 'c');
anagram('ac', 'b');
这些调用中的第二个将导致另一个调用anagram
,其中包含以下参数:
anagram('acb', '');
当str
现在为空时,它被添加到uniqueOutput
只有在执行了所有这些操作之后,代码才会返回到最外层的anagram
调用,i
将根据您的注释递增:
//second iteration: i = 1. we are still in the original call from line 37.
您错过了第二次迭代。。这是注释中的执行流:
// anagram('', 'abc') level 0
// condition false... level 0
// first iteration: i = 0 level 0
// anagram(a', 'bc') ( creating new execution context level 1 )
// condition false.. level 1
// iteration 1... level 1
// anagram('ab', 'c') ( creating new execution context level 2 )
// condition false.. level 2
// iteration 1... level 2
// anagram('abc', '') ( creating new execution context level 3 )
// condition true.. push "abc"
// end for of level 2 context execution
// iteration 2... level 1
// anagram('ac', 'b') ( creating new execution context level 2 )
// condition false.. level 2
// iteration 1... level 2
// anagram('acb', '') ( creating new execution context level 3 )
// condition true.. push "abc" level 3
// end for of level 2 execution
// end for of level 1
// second iteration of level 0....
// keep this pattern till end for of level 0..
// end anagram level 0
如您所见,级别0的每次迭代都将向对象推送2个单词。如果我们遵循您的逻辑,每个迭代只推进一个,考虑到递归就像在那个确切的位置添加更多的代码,函数调用完成后,执行流将返回到调用函数之前的位置。在第一次迭代中,您将错过第一次对anagram调用的第二次迭代,而第一次迭代真正澄清了这一点。我在反复思考,忘记了对anagram的初始调用也将以相同的方式递归计算!在顶层调用中,在“abc”和“acb”路径都完成执行之前,即在我的帖子中提到的所有调用之后,我不会从0递增到1。然后我将递增到1,代码将完全通过'bac'和'bca'路径,然后我将递增到2,代码将完全通过'cab'和'cba'路径(答案更新),明白了吗。所以在字谜之前('acb','');执行,字谜('ab','c')-->字谜('abc','')已经执行并存储在uniqueOutput中?在所有这些都完成之后,然后在外部级别开始i++的过程,例如,字谜(“+”b“,”a“+”c”)->字谜(“b”,“ac”),然后必须循环“ac”?是的,就是这样,谢谢!我正在用更新的(更好的)解释尝试更新我的问题。我想我明白了!我不明白为什么当你从字谜('ab','c')到字谜('abc','')时我们仍然在迭代一中?我认为这是在第二次迭代中发生的?因为您处于执行上下文的内部级别,所以在级别0中有3次迭代,对吗?以“a”开头。。从“b”开始,从“c”开始,但一旦进入级别0的第一次迭代,就会有另一个对anagram的调用,这会创建另一个内部执行上下文,即级别1,并且对于该级别,也有迭代。。与外部级别中的迭代相比,您需要首先进行迭代,对于更多的内部级别,这一点与级别2相同。
// anagram('', 'abc') level 0
// condition false... level 0
// first iteration: i = 0 level 0
// anagram(a', 'bc') ( creating new execution context level 1 )
// condition false.. level 1
// iteration 1... level 1
// anagram('ab', 'c') ( creating new execution context level 2 )
// condition false.. level 2
// iteration 1... level 2
// anagram('abc', '') ( creating new execution context level 3 )
// condition true.. push "abc"
// end for of level 2 context execution
// iteration 2... level 1
// anagram('ac', 'b') ( creating new execution context level 2 )
// condition false.. level 2
// iteration 1... level 2
// anagram('acb', '') ( creating new execution context level 3 )
// condition true.. push "abc" level 3
// end for of level 2 execution
// end for of level 1
// second iteration of level 0....
// keep this pattern till end for of level 0..
// end anagram level 0