给定一个值数组:
var values = new Array();
array.push(2);
array.push(3);
array.push(4);
我想创建一个迭代函数,可以存储所有可能的值组合,对于任何长度的数组。
为例,在这种情况下,可能的值(1,1,1)(1,1,2)(1,1,3)(1,- 1,4)(1、2、1)(1、2、2)(1、2、3)(1、2、4)(2,1,1)(2,1,2)(2,1,3)(2,1,4)(2,2,1)(2 2 2)(2,2,3)(2,2,4)
我知道要做到这一点,我需要使用递归函数,它将进入更深一层,如果没有达到最大深度,则再次调用该函数…
我知道从哪里开始(可能,我认为)
function iterativeLoop(level, depth) {
for(var i = 0; i < values.length; i++) {
if(level < depth) {
iterativeloop(level+1, depth);
}
else if (level=depth) {
}
}
}
我不确定如何访问"上层"级别,一旦函数被称为更深的虽然…例如,我不确定如何访问(1,2,4)而不仅仅是(?,?,4)
我希望这是有意义的?
(对不起,我知道我的标题不是很好,我不知道如何简明地解释它)
我不确定如何访问"上层"级别,一旦函数被称为更深的虽然…例如,我不确定如何访问(1,2,4)而不仅仅是(?,?,4)
你需要传递它们,例如在数组中。
for(var i = 0; i < values.length; i++)
这不应该是要执行的外层迭代,除非你想在一个简单的嵌套循环中构造一个二维数组的结果(见下文)。相反,你想让value.length
成为递归到的深度。在每个递归级别上,您将从1迭代到values[level]
。而不是传递一个level
,我们将传递一个当前状态的数组(上面的问号),其长度为level.
var values = [2,3,4];
function recurse(state) {
var level = state.length;
var depth = values.length;
if (level == depth) {
console.log.apply(console, state); // or whatever you want to do
} else {
for (var i=1; i<=values[level]; i++) {
state.push(i); // save current question mark
// notice state.length = level + 1 now
recurse(state); // enter next level
state.pop(); // delete it after we're so state doesn't grow infinitely :-)
}
}
}
recurse([]);
如果您想对这些值进行迭代,可以通过向结果数组中添加越来越多的状态(每层增加一个值)来实现,最终将包含所有可能的组合:
var values = [2,3,4];
var result = [[]]; // one empty state at level 0
for (var i=0; i<values.length; i++) {
var reslen = result.length,
val = values[i];
var mult = []; // will become the new result with a length of (reslen * val)
for (var j=0; j<reslen; j++) {
for (var k=1; k<=val; k++) {
var state = result[j].slice(); // make a copy
state.push(k);
mult.push(state);
}
}
result = mult;
}
// logging the `result` on each level will show us
// 0 - [[]]
// 1 - [[1],[2]]
// 2 - [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3]]
// 3 - [[1,1,1],[1,1,2],[1,1,3],[1,1,4],[1,2,1],[1,2,2],[1,2,3],[1,2,4],[1,3,1],[1,3,2],[1,3,3],[1,3,4],[2,1,1],[2,1,2],[2,1,3],[2,1,4],[2,2,1],[2,2,2],[2,2,3],[2,2,4],[2,3,1],[2,3,2],[2,3,3],[2,3,4]]
您可以看到这与@Jason的方法有多么相似。
你不需要递归,因为任意数据集的长度是在运行时开始定义的:
var numbers = [2,3,4];
var result_array = [];
var num_product = 1;
var i=0, j=0, k=0; // iterators
for (i=0; i<numbers.length; i++) {
num_product *= numbers[i];
}
for (i=0; i<num_product; i++) {
result_array.push([]);
}
for (i=0; i<result_array.length; i++) {
product = 1;
for (j=0; j<numbers.length; j++) {
k = (Math.floor(i/product)%numbers[j]) + 1;
product *= numbers[j];
result_array[i][j] = k;
}
}
已经过测试,可用于任意数量的数组元素。
一个并行的基准测试显示,这段代码比递归代码要快得多——如果你能够避免递归(例如,你预先知道足够的信息来定义整个问题),那么最好这样做,并且当前定义的问题允许你这样做。如果你只是想学习递归,那么这对你不是很有帮助:)