配列の可能なすべてのサブセットを取得する必要があります。
私がこれを持っていると言います:
[1, 2, 3]
どうすれば入手できますか?
[], [1], [2], [1, 2], [2, 3], [1, 3], [1, 2, 3]
すべてのサブセットに興味があります。特定の長さのサブセットについては、次の質問を参照してください。
次に、ループと再帰を使用せず、マップと配列のネイティブ関数のみを使用する非常にエレガントなソリューションを示します。
const getAllSubsets =
theArray => theArray.reduce(
(subsets, value) => subsets.concat(
subsets.map(set => [value,...set])
),
[[]]
);
console.log(getAllSubsets([1,2,3]));
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ⁿ)に比例します。
別のシンプルなソリューション。
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; }
次のようなものを使用して、配列から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
配列にプッシュされます。
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;
}
これは再帰的です
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