我正在尝试创建以下嵌套循环的递归版本并获得与引用代码相同的结果。示例如下。
这是 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
递归代码和输出:
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 ]
不确定我在这里遗漏了什么。
最佳答案
你的代码中有一个小错误:
您从 i + 1
调用递归函数,但不是你的 index + 1
.
它导致index
不等于当前数组索引,而是它的值。
例如,当您通过 [0, 1, 2]
,你现在的数据是[0, 1]
你将要插入 3
, 你调用 loop(3 + 1)
, index
4 超出数组范围。 if (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);
这是工作 JSFiddle demo .
更新:
哦,现在我明白了。你需要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
Updated JSFiddle demo with passing argument .
如果您认为它不对,您可以检查之前的值而不是将值作为参数传递。条件类似于“如果它是第一个数字,从 0 开始;否则 - 从前一个数字之后的下一个数字开始”。
var start = (index === 0 ? 0 : data[index-1] + 1);
关于javascript - 尝试将嵌套循环转换为递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31979661/