找到数组项的nCr组合

时间:2011-06-15 14:29:45

标签: javascript math

我的递归函数在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 );

1 个答案:

答案 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