我试图理解下面的递归函数,以自学递归。我试图解释它的过程低于预期的输出和函数本身。我想念什么?我没有看到从“abc”到“acb”的过程。我的理解使我从'abc'变成了'bac'。

    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.

我的新的,正确的(我认为)解释是:
//initial input: anagram("", "abc")
//STEP 1: enter the function --> i = 0 for original string "abc"
  //anagram("" + "a", "bc") ----> anagram("a", "bc")
//STEP 2: loop through the new, modified string, which is now "bc"
    //var i = 0;
    //anagram("a" + "b", "c")---> anagram("ab", "c")
    //anagram("ab" + "c", [nothing here])
      //base case hit, so uniqueOutput["abc"] = 1;
    //var i = 1; --> this applies to the string "bc". the loop gets reset to i = 0 once you have a new string to worth with (like below, with "b")
    //anagram("a" + "c", "b")
    //anagram("ac", "b")
    //anagram("ac" + "b", "" )
      //base case hit, so uniqueOutput["acb"] = 1;
//STEP 3: increment up on the original string input ("abc") --> so now you are dealing with str[i] === b
  //var i =  1;
  //anagram("" + "b", "a" + "c")
    //anagram("b", "ac")  ---> now we need to loop through "ac"!
      //anagram("b" + "a", "c")
        //anagram("ba", "c")
          //anagram("bac", "")---> base case hit, uniqueOutput["bac"] = 1;
    //anagram("b", "ac")
      //anagram("b" + "c", "a") ---> anagram("bc", "a")
        //anagram("bca", "") ---> base case hit, uniqueOutput["bca"] = 1;
//STEP 4: increment up on the original string input ("abc") ---> str[i] === c
  //var i = 2;
  //anagram ("" + "c", "ab")---> anagram("c", "ab")
    //now we need to loop through "ab!" c's index stays the same.
    //anagram("c" + "a", "b") ---> anagram("ca", "b")
      //anagram("cab", '')---> uniqueOuput["cab"] = 1;
    //anagram("c" + "b", "a") ---> anagram("cb", "a")
      //anagram("cba", "")----> uniqueOutput["cba"] = 1

最佳答案

根据您上面的评论:

// first iteration: i = 0
// anagram('' + 'a' + 'bc' [from str.slice(0 +1)]) ---> resolves to "abc") --->

实际上在i = 0上,传递给anagram的参数是:
anagram('' + 'a', '' + 'bc');

结果为:
anagram('a', 'bc');

然后,在对anagram的调用中,我们再次遍历str,现在它只是“bc”。这将导致对anagram的2次调用,这将是
anagram('a' + 'b', '' + 'c'); // i = 0
anagram('a' + 'c', 'b' + ''); // i = 1

评估结果为:
anagram('ab', 'c');
anagram('ac', 'b');

这些调用中的第二个将导致使用以下参数再次调用anagram:
anagram('acb', '');

由于uniqueOutput现在为空,因此已添加到str中。

只有执行完所有代码后,代码才会返回到anagrami的最外层调用,具体取决于您的注释:
//second iteration: i = 1. we are still in the original call from line 37.

10-06 12:28