写穿过嵌套循环

问题描述:

的一个未知的深度给定的值的阵列迭代递归函数:写穿过嵌套循环

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,1,1)(1,1,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)

我希望这是有道理的?

(对不起,我知道我的标题不是很好,我想不出如何简明地解释)

+2

您正在寻找的单词是“递归”的,而不是“迭代的”(如果您正在搜索,可能会有所帮助)。如果我得到一分钟,我会写一个例子。 – Jason 2013-04-11 14:54:42

+0

啊哎呀谢谢你! – Eilidh 2013-04-11 14:57:08

+0

另外,可能没有必要。现在写一个答案。 – Jason 2013-04-11 14:58:36

你不需要递归,因为任意数据集的长度在一开始被定义运行时:

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; 
    } 
} 

已测试并可用于任意数量的数组元素。

A side-by-side benchmark说明此代码比递归码显著快 - 如果你是能够避免递归(例如,你知道足够的信息,在锋线上能够定义整个问题),那么它是更好地做到这一点,目前定义的问题可以让你做到这一点。如果你只是想了解递归,那么这对你不是很有帮助:)

+1

Wheres递归消失^^ – C5H8NNaO4 2013-04-11 15:38:24

+0

正如我对原始问题的评论,我认为这更适合于非递归方法,我的印象是他不需要递归,他只是认为这是必要的。不幸的是我有点仓促,我认为我的解决方案不管怎么样。稍后当我有一点时间时,我会回来看看它。 – Jason 2013-04-11 16:41:33

+0

我确实需要它,因为我发布我希望它可以用于*任何*长度的数组。三长阵列只是一个例子。 – Eilidh 2013-04-11 16:43:57

我不知道如何一旦函数被调用的更深,我可以访问'上'的水平。 ..即我不知道如何访问(1,2,4),而不仅仅是(?,?,4)

您将需要通过它们,例如在一个数组中。

for(var i = 0; i < values.length; i++) 

这不应该进行外部循环,除非要构造以简单的嵌套循环结果的二维阵列(见下文)。相反,您希望value.length成为您正在递归的深度。在每个递归级别上,您将重复从1到values[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的方法类似。