堆的算法排列JavaScript和递归'堆?

时间:2016-09-09 12:27:56

标签: javascript algorithm recursion

我有一个基于Heap算法排列计算重复字符串的赋值。我想要做的第一件事就是输出交换字符串,我从jake's answer找到了这段代码。有人可以请帮助我在循环中了解此代码中的递归?该函数的输出是交换字符串。

function permAlone(string) {

var arr = string.split(''),   // Turns the input string into a letter array.
          permutations = []; // results

function swap(a, b) {  
debugger; // This function will simply swap positions a and b inside the input array.
var tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}

function gen(n) {   
  debugger;
  if (n === 1) {  
  var x =arr.join('');
  permutations.push(x);  
  } else {
  for (var i = 0; i != n; i++) { // how does this loop executes within the call stack?  
    gen(n - 1);
    debugger;
    swap(n % 2 ? 0 : i, n - 1); // i don't understand this part. i understand the swap function, but I don't get how indexes are swapped here
  }   
 }
}
 gen(arr.length);
 return permutations;
}
permAlone('xyz'); // output -> ["xyz","yxz","zxy","xzy","yzx","zyx"]

我一直在调试器上进行实验,但仍然无法解决问题。

1 个答案:

答案 0 :(得分:3)

我不确定你的意思

  

理解循环中此代码中的递归

如果你的意思是想要以循环形式而不是递归版本看到算法,你可以在wikipedia page here中以伪代码的形式看到它们。

代码中的问题:

  

这个循环如何在调用堆栈中执行?

你是正确的参考调用堆栈,这是一个关于递归的一般问题。如果您不了解递归如何与堆栈一起工作,您可以参考this really nice and simple video,它使用java中的因子计算来演示递归调用(从最小值4:00开始)。

您看到的行与递归函数中的任何其他行没有什么不同。我们首先定义i并为其赋值0。我们继续检查它是否满足for循环的条件。如果是,我们进入循环并执行循环内的第一行,即递归调用。在递归调用中,我们有一个新的堆栈帧,它不知道我们在执行递归调用之前定义的i变量,因为它是一个局部变量。因此,当我们在新调用中进入循环时,我们定义一个新变量i,首先将其赋值为0,并在循环在此堆栈帧/调用实例中重复时递增它。当这个调用结束时,我们删除堆栈帧并恢复到前一个堆栈帧(我们开始的那个),其中i = 0仍然是,我们继续到下一行。 所有调用都可以访问arr和permutations变量,因为函数定义在与变量相同的范围内(函数permAlone内)所以在每次调用中 - 无论我们所处的堆栈帧是什么,对它们所做的更改都是对同样的例子做了。这就是为什么每次对排列做出的推动都会增加现有结果的原因,并且当函数在最后返回变量时它将会存在。

  

我不明白这一部分。我理解交换功能,但我不知道如何交换索引

此处未交换索引。它只是调用具有正确索引的交换函数。

swap(n % 2 ? 0 : i, n - 1);

只是

swap(a, b);

a = n% 2 ? 0 : i;
b = n - 1;

如果a部分让您感到困惑,那么这是the ternary operator for conditional value的使用。也就是说,它用于形成表达式的符号,该表达式根据情况进行不同的评估。 <使用是

<<i>boolean epression</i>> ? <<i>value-if-true</i>> : <<i>value-if-false</i>>

评估上述,第一个&lt; 布尔表达式&gt;被评估。如果它将值true,那么整个表达式将被评估为&lt; value-if-true &gt;。否则,整个表达式被评估为&lt; value-if-false &gt;。

在代码本身中,对于an % 2是布尔表达式 - js将n除以2并取余数。余数为10。 js分别将这些转换为truefalse。因此,如果n是奇数,我们会得到

a = 0

如果它甚至我们得到了

a = i
算法要求