我正在尝试创建以下嵌套循环的递归版本,并获得与参考代码相同的结果。示例如下。
这是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 ]
不确定我在这里缺少什么。
答案 0 :(得分: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);
答案 1 :(得分:2)
当你有三个for循环时,你必须为递归函数传递2个参数。
var len = 4;
var end = 3;
var data = [];
var loop = function(start, index) {
if (index === end) {
console.log(data);
return;
}
for (var i = start; i < len; i++) {
data[index] = i;
loop(i + 1, index + 1); //Pass as like a+1 & b+1
}
}
loop(0, 0);
答案 2 :(得分:2)
有几个错误;您从i+1
而不是index+1
开始递归,而您从index
开始计算而不是从data[index-1]+1
开始计算。
更正后的版本是:
var len = 4;
var end = 3;
var data = [];
var loop = function (index) {
if (index === end) {
console.log(data);
return;
}
for (var i = (index==0 ? 0 : data[index-1]+1); i < len; i++) {
data[index] = i;
loop(index + 1);
}
}
答案 3 :(得分:0)
输出确切的预期结果。
var len = 4;
var end = 3;
var data = [];
var loop = function(i) {
if(data.length === end) {
// console.log(data); -> Wont work in snippet
// Snippet workaround
document.getElementsByTagName('body')[0].innerHTML += data.join(',') + '<br/>';
return;
}
if(i >= len)
return;
data.push(i);
loop(i + 1);
data.pop();
loop(i + 1);
};
loop(0);