我需要使用最少的2
项目和未知的最大值来获取数组的所有可能子集。谁能帮我一下?
假设我有以下数组:
[1, 2, 3]
我怎么得到这个?
[
[1, 2],
[1, 3],
[2, 3],
[1, 2, 3]
]
我需要使用最少的2
项目和未知的最大值来获取数组的所有可能子集。谁能帮我一下?
假设我有以下数组:
[1, 2, 3]
我怎么得到这个?
[
[1, 2],
[1, 3],
[2, 3],
[1, 2, 3]
]
在窃取了这个JavaScript 组合生成器之后,我添加了一个参数来提供最小长度,结果是,
var combine = function(a, min) {
var fn = function(n, src, got, all) {
if (n == 0) {
if (got.length > 0) {
all[all.length] = got;
}
return;
}
for (var j = 0; j < src.length; j++) {
fn(n - 1, src.slice(j + 1), got.concat([src[j]]), all);
}
return;
}
var all = [];
for (var i = min; i < a.length; i++) {
fn(i, a, [], all);
}
all.push(a);
return all;
}
要使用,请提供一个数组和所需的最小子集长度,
var subsets = combine([1, 2, 3], 2);
输出是,
[[1, 2], [1, 3], [2, 3], [1, 2, 3]]
组合,简短的一个:
function combinations(array) {
return new Array(1 << array.length).fill().map(
(e1, i) => array.filter((e2, j) => i & 1 << j));
}
console.log(combinations([1, 2, 3]).filter(a => a.length >= 2))
通过这个问题的一个小调整,我希望我的解决方案更有效,因为它使用位运算符来生成所有子集。
var sets = (function(input, size) {
var results = [], result, mask, i, total = Math.pow(2, input.length);
for (mask = size; mask < total; mask++) {
result = [];
i = input.length - 1;
do {
if ((mask & (1 << i)) !== 0) {
result.push(input[i]);
}
} while (i--);
if (result.length >= size) {
results.push(result);
}
}
return results;
})(['a','b','c','d','e','f'], 2);
console.log(sets);
这个算法要求递归……这就是我要做的
var arr = [1,2,3,4,5];
function getSubArrays(arr){
if (arr.length === 1) return [arr];
else {
subarr = getSubArrays(arr.slice(1));
return subarr.concat(subarr.map(e => e.concat(arr[0])), [[arr[0]]]);
}
}
console.log(JSON.stringify(getSubArrays(arr)));
上述算法的另一个奇特版本;
var arr = [1,2,3,4,5],
sas = ([n,...ns],sa) => !ns.length ? [[n]]
: (sa = sas(ns),
sa.concat(sa.map(e => e.concat(n)),[[n]]));
为了了解发生了什么让我们一步一步
getSubArrays
使用参数数组的尾部调用相同的函数。所以尾部[1,2,3,4,5]
是[2,3,4,5]
。[5]
我们返回[[5]]
到前一个getSubArrays
函数调用。getSubArrays
功能arr
是[4,5]
和subarr
被分配到[[5]]
。[[5]].concat([[5]].map(e => e.concat(4), [[4]])
实际上[[5], [5,4], [4]]
是上一个getSubArrays
函数调用。getSubArrays
功能arr
是[3,4,5]
和subarr
被分配到[[5], [5,4], [4]]
。这是一种使用 ECMAScript 2015生成器函数查找所有组合的方法:
要限制为问题中要求的最小尺寸,只需在产生组合之前确保组合的长度:
function* generateCombinations(arr, minSize) {
function* doGenerateCombinations(offset, combo) {
if (combo.length >= minSize) {
yield combo;
}
for (let i = offset; i < arr.length; i++) {
yield* doGenerateCombinations(i + 1, combo.concat(arr[i]));
}
}
yield* doGenerateCombinations(0, []);
}
for (let combo of generateCombinations([1, 2, 3, 4, 5], 2)) {
console.log(JSON.stringify(combo));
}
在点上yield
进行限制允许以一种可读的方式将此功能调整到其他常见用例,例如,选择精确大小的所有组合: