我的递归函数在Array中找到 nCr 对象时遇到问题。
这仅适用于r=2
,仅指在内部达到1级时。
似乎我的临时'a'
数组在r > 2
// find nCr combinations in Array
// n -> keys.length
// r -> number of combination to extract (cross = r-1 )
console.clear();
var keys = [0,1,2,3,4,5];
// cross = 'r'-1, s = start point, a = array
function recursive(cross, s, a){
for( var i=s; i < keys.length; i++ ){
if( !cross ){
var b = a.slice(0);
b.push( keys[i] );
set.push( b );
}
else{
a.splice(-1, 1);
a.push(keys[i]);
recursive(cross-1, i+1, a);
}
}
}
var set = [];
recursive(1, 0, []);
console.log( set );
答案 0 :(得分:4)
我不确定您在else
条件下究竟要做什么:请注意a.splice(-1,1)
删除a
的最后一个元素,但是从{{1}开始空的,没有什么可以删除的。即使代码适用于a
,这也表明您做错了。 (事实上,每次你更深入一级时,r=2
都会以与上一级相同数量的元素开始,所以你要删除一些你不应该触及的元素。)
这是对算法的一个非常小的修改,它可以正常工作。我只是更改了a
条件中的语句顺序。
else
最后一部分应打印var keys = [0,1,2,3,4,5];
function recursive(cross, s, a) {
for( var i=s; i < keys.length; i++ ){
if( !cross ){
var b = a.slice(0);
b.push( keys[i] );
set.push( b );
}
else{
a.push(keys[i]);
recursive(cross-1, i+1, a);
a.splice(-1, 1);
}
}
}
var set = [];
recursive(4, 0, []);
console.log( set );
中的所有(6选5)= 5个元素的6种组合。
现在的想法是,现在在函数的每次调用中,keys
只删除在该调用中添加的元素,而不是某些其他函数调用中可能添加的某些其他级别。这也保证了splice
在结束时与开始时保持一致。 (您添加的所有内容都会再次删除。)
这是编写递归函数时常见的模式:做一些修改,递归调用函数,然后进行一些反转修改的清理。
BTW,稍微清晰的代码(没有a
混淆)在the first revision of this answer。