web-dev-qa-db-ja.com

JavaScriptでセットのすべてのサブセットを見つける方法は?

配列の可能なすべてのサブセットを取得する必要があります。

私がこれを持っていると言います:

[1, 2, 3]

どうすれば入手できますか?

[], [1], [2], [1, 2], [2, 3], [1, 3], [1, 2, 3]

すべてのサブセットに興味があります。特定の長さのサブセットについては、次の質問を参照してください。

  • サイズnのサブセットの検索: 12
  • サイズ> 1のサブセットの検索 1
27
le_m

次に、ループと再帰を使用せず、マップと配列のネイティブ関数のみを使用する非常にエレガントなソリューションを示します。

const getAllSubsets = 
      theArray => theArray.reduce(
        (subsets, value) => subsets.concat(
         subsets.map(set => [value,...set])
        ),
        [[]]
      );

console.log(getAllSubsets([1,2,3]));
28
MennyMez

offsetから始まる入力配列のサブセットでこの問題を解決できます。その後、再帰的に戻って完全なソリューションを取得します。

ジェネレータ関数 を使用すると、一定のメモリ使用量でサブセットを反復処理できます。

// Generate all array subsets:
function* subsets(array, offset = 0) {
  while (offset < array.length) {
    let first = array[offset++];
    for (let subset of subsets(array, offset)) {
      subset.Push(first);
      yield subset;
    }
  }
  yield [];
}

// Example:
for (let subset of subsets([1, 2, 3])) {
  console.log(subset); 
}

実行時の複雑さは、ソリューションの数(2ⁿ)×ソリューションあたりの平均長(n/2)=O(n2ⁿ)に比例します。

18
le_m

別のシンプルなソリューション。

function getCombinations(array) {

    function fork(i, t) {
        if (i === array.length) {
            result.Push(t);
            return;
        }
        fork(i + 1, t.concat([array[i]]));
        fork(i + 1, t);
    }

    var result = [];
    fork(0, []);
    return result;
}

var data = [1, 2, 3],
    result = getCombinations(data);
        
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
7
Nina Scholz

次のようなものを使用して、配列からpowersetを簡単に生成できます。

var arr = [1, 2, 3];

function generatePowerSet(array) {
  var result = [];
  result.Push([]);

  for (var i = 1; i < (1 << array.length); i++) {
    var subset = [];
    for (var j = 0; j < array.length; j++)
      if (i & (1 << j))
        subset.Push(array[j]);

    result.Push(subset);
  }

  return result;
}

console.log(generatePowerSet(arr));

関数のメインループ全体で、サブセットが作成され、result配列にプッシュされます。

7
let subsets = (n) => {

let result = [];
result.Push([]);

n.forEach(a => {

  //array length
   let length = result.length;
    let i =0;

    while(i < length){

      let temp = result[i].slice(0);
      temp.Push(a);

      result.Push(temp);
      i++;

    }
})

return result;
}
1
ASHISH RANJAN

これは再帰的です

var subsets = function(s){
  if(s.length === 0) {
    return [[]]
  }
  var h,t,ss_excl_h;
  var ss_incl_h = [];
  [h,...t] = s;
  ss_excl_h = subsets(t)
  for(ss of ss_excl_h) {
    let hArr = [];
    hArr.Push(h);
    let temp = hArr.concat(ss)
    ss_incl_h.Push(temp);
  }
  return ss_incl_h.concat(ss_excl_h)
}

console.log(subsets([1,2,3])) // returns distinct subsets
0
pride