试图将嵌套循环转换为递归函数

Geu*_*uis 5 javascript recursion

我正在尝试创建以下嵌套循环的递归版本,并获得与参考代码相同的结果.示例如下.

这是Codepen http://codepen.io/anon/pen/XbQMLv上的一个版本

(代码的目的是仅输出索引中唯一的整数组合.)

原始代码和输出:

var len = 4;

for (var a = 0; a < len; a++) {
  for (var b = a + 1; b < len; b++) {
    for (var c = b + 1; c < len; c++) {
      console.log(a, b, c);
    }
  }
}
// Outputs:
// 0 1 2
// 0 1 3
// 0 2 3
// 1 2 3
Run Code Online (Sandbox Code Playgroud)

递归代码和输出:

var len = 4;
var end = 3;
var data = [];

var loop = function (index) {
  if (index === end) {
    console.log(data);
    return;
  }
  for (var i = index; i < len; i++) {
    data[index] = i;
    loop(i + 1);
  }
}

loop(0);
// Outputs:
// [ 0, 1, 2 ]
// [ 0, 2, 3 ]
// [ 1, 3, 2 ]
// [ 2, 3, 3 ]
Run Code Online (Sandbox Code Playgroud)

不知道我在这里缺少什么.

Yel*_*yev 4

您的代码中有一个小错误:

您从您的 调用递归函数i + 1,但不是从您的index + 1.
它导致index等于的不是当前数组索引,而是它的值。

例如,当您传递 时[0, 1, 2],您的数据现在是[0, 1]并且您即将插入,3您调用4 超出了数组范围。条件失败,不输出。循环也失败了,一切都出了问题。loop(3 + 1)indexif (index === end)for (var i = index; i < len; i++)

它应该是:

var len = 4;
var end = 3;
var data = [];

var loop = function (index) {
  if (index === end) {
    console.log(data);
    return;
  }
  for (var i = index; i < len; i++) {
    data[index] = i;
    loop(index + 1); // <--- HERE
  }
}

loop(0);
Run Code Online (Sandbox Code Playgroud)

这是工作中的JSFiddle 演示

更新:

哦,现在我明白了。您需要a[i] > a[i-1]条件对于所有组合都为真。只需添加一个start变量来保存最后插入的值即可遵守此规则。

var len = 4;
var end = 3;
var data = [];

var loop = function (start, index) {
  if (index === end) {
    document.body.innerHTML += "<br/>" + data;
    return;
  }
  for (var i = start; i < len; i++) { // We start from 'start' (the last value + 1)
    data[index] = i;
    loop(i + 1, index + 1); // Here, we pass the last inserted value + 1
  }
}

loop(0, 0); // At beginning, we start from 0
Run Code Online (Sandbox Code Playgroud)

通过传递参数更新了 JSFiddle 演示

如果您认为前一个值不对,您可以检查前一个值,而不是将值作为参数传递。条件类似于“如果是第一个数字,则从 0 开始;否则 - 从上一个数字之后的下一个数字开始”。

var start = (index === 0 ? 0 : data[index-1] + 1);  
Run Code Online (Sandbox Code Playgroud)

更新了 JSFiddle 演示并计算 start