给定一个数组,如何生成子集大小k的所有组合?

时间:2017-10-22 23:20:15

标签: javascript algorithm subset permutation combinatorics

因此,{@ 1}}和input = [1, 2, 3]会返回:

k=2

这是我最接近我想要的,但不完全是:http://algorithms.tutorialhorizon.com/print-all-combinations-of-subset-of-size-k-from-given-array/

1 2
1 3
2 1
2 3
3 1
3 2

^缺少function subsetsOfSize(a, used, startIndex, currentSize, k) { if (currentSize === k) { for (var i = 0; i < a.length; i++) { if (used[i]) console.log(a[i]); } console.log('-'); return; } if (startIndex === a.length) return; used[startIndex] = true; subsetsOfSize(a, used, startIndex+1, currentSize+1, k); used[startIndex] = false; subsetsOfSize(a, used, startIndex+1, currentSize, k); } var input = [1,2,3]; subsetsOfSize(input, Array(input.length).fill(false), 0, 0, 2);2 13 1等结果

其次,我不确定我是否正确地命名了这个问题,因为“大小为k的子集的所有组合”的解决方案没有给出预期的答案。

3 个答案:

答案 0 :(得分:3)

查找k子集排列的递归解决方案(伪代码):

kSubsetPermutations(partial, set, k) {
    for (each element in set) {
        if (k equals 1) {
            store partial + element
        }
        else {
            make copy of set
            remove element from copy of set
            recurse with (partial + element, copy of set, k - 1)
        }
    }
}

以下是一个例子:

  

输入:[a,b,c,d,e]
  k:3

partial = [], set = [a,b,c,d,e], k = 3
    partial = [a], set = [b,c,d,e], k = 2
        partial = [a,b], set = [c,d,e], k = 1 -> [a,b,c], [a,b,d], [a,b,e]
        partial = [a,c], set = [b,d,e], k = 1 -> [a,c,b], [a,c,d], [a,c,e]
        partial = [a,d], set = [b,c,e], k = 1 -> [a,d,b], [a,d,c], [a,d,e]
        partial = [a,e], set = [b,c,d], k = 1 -> [a,e,b], [a,e,c], [a,e,d]
    partial = [b], set = [a,c,d,e], k = 2
        partial = [b,a], set = [c,d,e], k = 1 -> [b,a,c], [b,a,d], [b,a,e]
        partial = [b,c], set = [a,d,e], k = 1 -> [b,c,a], [b,c,d], [b,c,e]
        partial = [b,d], set = [a,c,e], k = 1 -> [b,d,a], [b,d,c], [b,d,e]
        partial = [b,e], set = [a,c,d], k = 1 -> [b,e,a], [b,e,c], [b,e,d]
    partial = [c], set = [a,b,d,e], k = 2
        partial = [c,a], set = [b,d,e], k = 1 -> [c,a,b], [c,a,d], [c,a,e]
        partial = [c,b], set = [a,d,e], k = 1 -> [c,b,a], [c,b,d], [c,b,e]
        partial = [c,d], set = [a,b,e], k = 1 -> [c,d,a], [c,d,b], [c,d,e]
        partial = [c,e], set = [a,b,d], k = 1 -> [c,e,a], [c,e,b], [c,e,d]
    partial = [d], set = [a,b,c,e], k = 2
        partial = [d,a], set = [b,c,e], k = 1 -> [d,a,b], [d,a,c], [d,a,e]
        partial = [d,b], set = [a,c,e], k = 1 -> [d,b,a], [d,b,c], [d,b,e]
        partial = [d,c], set = [a,b,e], k = 1 -> [d,c,a], [d,c,b], [d,c,e]
        partial = [d,e], set = [a,b,c], k = 1 -> [d,e,a], [d,e,b], [d,e,c]
    partial = [e], set = [a,b,c,d], k = 2
        partial = [e,a], set = [b,c,d], k = 1 -> [e,a,b], [e,a,c], [e,a,d]
        partial = [e,b], set = [a,c,d], k = 1 -> [e,b,a], [e,b,c], [e,b,d]
        partial = [e,c], set = [a,b,d], k = 1 -> [e,c,a], [e,c,b], [e,c,d]
        partial = [e,d], set = [a,b,c], k = 1 -> [e,d,a], [e,d,b], [e,d,c]

&#13;
&#13;
function kSubsetPermutations(set, k, partial) {
    if (!partial) partial = [];                 // set default value on first call
    for (var element in set) {
        if (k > 1) {
            var set_copy = set.slice();         // slice() creates copy of array
            set_copy.splice(element, 1);        // splice() removes element from array
            kSubsetPermutations(set_copy, k - 1, partial.concat([set[element]]));
        }                                       // a.concat(b) appends b to copy of a
        else document.write("[" + partial.concat([set[element]]) + "] ");
    }
}
kSubsetPermutations([1,2,3,4,5], 3);
&#13;
&#13;
&#13;

答案 1 :(得分:1)

尝试排列。而不是组合。

尝试生成排列,然后调整数组大小。

此处已实施,已从here修改

&#13;
&#13;
var permArr = [],
  usedChars = [];

function permute(input, k) {
  var i, ch;
  for (i = 0; i < input.length; i++) {
    ch = input.splice(i, 1)[0];
    usedChars.push(ch);
    if (input.length == 0) {
      var toadd = usedChars.slice(0,k);
      if(!permArr.includes(toadd)) permArr.push(toadd); // resizing the returned array to size k
    }
    permute(input, k);
    input.splice(i, 0, ch);
    usedChars.pop();
  }
  return permArr
};
console.log(JSON.stringify(permute([1, 2, 3], 2)));
&#13;
&#13;
&#13;

答案 2 :(得分:0)

我是一个简单的人:

制作一个大小为k

的数组M.

用零填充M

循环:

M [0] + = 1

循环M:* if(M [i]> = N的大小)然后设置M [i] = 0并增加M [i + 1] + = 1

如果M只有不同的数字,那么你就会发现自己是a的指数 n的子集

当p的最后一个元素达到n的大小时,

循环结束 - 减去一个a.k.a. *条件会导致错误