Javascript 是否在数组中查找所有可能的子集组合?
我需要得到一个数组的所有可能子集,其中最少有Javascript 是否在数组中查找所有可能的子集组合?,javascript,arrays,subset,Javascript,Arrays,Subset,我需要得到一个数组的所有可能子集,其中最少有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
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;
}
产出是,
[[1, 2], [1, 3], [2, 3], [1, 2, 3]]
我已经修改了接受的解决方案,当min等于0时考虑空集(空集是任何给定集合的子集)。
这是一个完整的示例页面,可以复制粘贴,可以运行一些输出
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>All Subsets</title>
<script type="text/javascript">
// get all possible subsets of an array with a minimum of X (min) items and an unknown maximum
var FindAllSubsets = 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 = [];
// empty set is a subset of the set (only when min number of elements can be 0)
if(min == 0)
all.push([-1]); // array with single element '-1' denotes empty set
for (var i = min; i < a.length; i++) {
fn(i, a, [], all);
}
all.push(a);
return all;
}
function CreateInputList(){
var inputArr = [];
var inputArrSize = 4;
var maxInputValue = 10;
for(i=0; i < inputArrSize; i++){
var elem = Math.floor(Math.random()*maxInputValue);
// make sure to have unique elements in the array
while(inputArr.contains(elem)){ // OR - while(inputArr.indexOf(elem) > -1){
elem = Math.floor(Math.random()*maxInputValue);
}
inputArr.push(elem);
}
return inputArr;
}
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
}
function ArrayPrinter(arr){
var csv = 'input = [';
var i = 0;
for(i; i<arr.length - 1; i++){
csv += arr[i] + ', ';
}
csv += arr[i];
var divResult = document.getElementById('divResult');
divResult.innerHTML += csv + ']<br />';
}
// assumes inner array with single element being '-1' an empty set
function ArrayOfArraysPrinter(arr){
var csv = 'subsets = ';
var i = 0;
for(i; i<arr.length; i++){
csv += '[';
var j = 0;
var inArr = arr[i];
for(j; j<inArr.length - 1; j++){
csv += inArr[j] + ', ';
}
// array with single element '-1' denotes empty set
csv += inArr[j] == -1 ? '<E>' : inArr[j];
csv += ']';
if(i < arr.length - 1)
csv += ' ';
}
csv += ' (# of subsets =' + arr.length + ')';
var divResult = document.getElementById('divResult');
divResult.innerHTML += csv + '<br />';
}
function Main(){
// clear output
document.getElementById('divResult').innerHTML = '';
// sample run (min = 0)
document.getElementById('divResult').innerHTML += '<hr/>MIN = 0 (must include empty set)<br />';
var list = CreateInputList();
ArrayPrinter(list);
var subsets = FindAllSubsets(list, 0);
ArrayOfArraysPrinter(subsets);
document.getElementById('divResult').innerHTML += '<hr />';
// sample run (min = 1)
document.getElementById('divResult').innerHTML += 'MIN = 1<br />';
var list = CreateInputList();
ArrayPrinter(list);
var subsets = FindAllSubsets(list, 1);
ArrayOfArraysPrinter(subsets);
document.getElementById('divResult').innerHTML += '<hr />';
// sample run (min = 2)
document.getElementById('divResult').innerHTML += 'MIN = 2<br />';
var list = CreateInputList();
ArrayPrinter(list);
var subsets = FindAllSubsets(list, 2);
ArrayOfArraysPrinter(subsets);
document.getElementById('divResult').innerHTML += '<hr />';
// sample run (min = 3)
document.getElementById('divResult').innerHTML += 'MIN = 3<br />';
var list = CreateInputList();
ArrayPrinter(list);
var subsets = FindAllSubsets(list, 3);
ArrayOfArraysPrinter(subsets);
document.getElementById('divResult').innerHTML += '<hr />';
// sample run (min = 4)
document.getElementById('divResult').innerHTML += 'MIN = 4<br />';
var list = CreateInputList();
ArrayPrinter(list);
var subsets = FindAllSubsets(list, 4);
ArrayOfArraysPrinter(subsets);
document.getElementById('divResult').innerHTML += '<hr />';
}
</script>
</head>
<body>
<input type="button" value="All Subsets" onclick="Main()" />
<br />
<br />
<div id="divResult"></div>
</body>
</html>
所有子集
//获取具有最小X(min)项和未知最大项的数组的所有可能子集
var FindAllSubsets=函数(a,最小值){
var fn=函数(n,src,got,all){
如果(n==0){
如果(got.length>0){
全部[全部长度]=got;
}
返回;
}
对于(var j=0;j-1){
elem=Math.floor(Math.random()*maxInputValue);
}
输入推送(elem);
}
返回输入端;
}
Array.prototype.contains=函数(obj){
var i=该长度;
而(我--){
如果(此[i]==obj){
返回true;
}
}
返回false;
}
功能阵列打印机(arr){
var csv='input=[';
var i=0;
对于(i;i,我希望我的解决方案更有效,因为它使用位运算符生成所有子集
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集=(函数(输入,大小){
var results=[],result,mask,i,total=Math.pow(2,input.length);
对于(掩码=大小;掩码<总计;掩码++){
结果=[];
i=输入长度-1;
做{
如果((掩码和(1=大小){
结果。推(结果);
}
}
返回结果;
})(['a'、'b'、'c'、'd'、'e'、'f'],2);
控制台日志(套);
如果元素顺序很重要:
// same values, different order:
[1,2]
[2,1]
[1,3]
[3,1]
你也可以考虑一个排列。
// ---------------------
// Permutation
// ---------------------
function permutate (src, minLen, maxLen){
minLen = minLen-1 || 0;
maxLen = maxLen || src.length+1;
var Asource = src.slice(); // copy the original so we don't apply results to the original.
var Aout = [];
var minMax = function(arr){
var len = arr.length;
if(len > minLen && len <= maxLen){
Aout.push(arr);
}
}
var picker = function (arr, holder, collect) {
if (holder.length) {
collect.push(holder);
}
var len = arr.length;
for (var i=0; i<len; i++) {
var arrcopy = arr.slice();
var elem = arrcopy.splice(i, 1);
var result = holder.concat(elem);
minMax(result);
if (len) {
picker(arrcopy, result, collect);
} else {
collect.push(result);
}
}
}
picker(Asource, [], []);
return Aout;
}
var combos = permutate(["a", "b", "c"], 2);
for(var i=0; i<combos.length; i++){
var item = combos[i];
console.log("combos[" + i + "]" + " = [" + item.toString() + "]");
}
//---------------------
//排列
// ---------------------
函数置换(src、minLen、maxLen){
minLen=minLen-1 | | 0;
maxLen=maxLen | | src.长度+1;
var Asource=src.slice();//复制原始文件,这样我们就不会将结果应用于原始文件。
var Aout=[];
var minMax=函数(arr){
var len=阵列长度;
如果(len>minLen&&len使用二进制数
// eg. [2,4,5] ==> {[],[2],[4],[5],[2,4],[4,5],[2,5], [2,4,5]}
var a = [2, 4, 5], res = [];
for (var i = 0; i < Math.pow(2, a.length); i++) {
var bin = (i).toString(2), set = [];
bin = new Array((a.length-bin.length)+1).join("0")+bin;
console.log(bin);
for (var j = 0; j < bin.length; j++) {
if (bin[j] === "1") {
set.push(a[j]);
}
}
res.push(set);
}
console.table(res);
//例如[2,4,5]==>{[],[2],[4],[5],[2,4],[4,5],[2,5],[2,4,5]}
var a=[2,4,5],res=[];
for(var i=0;i
这个算法需要递归……我就是这样做的
var-arr=[1,2,3,4,5];
函数GetSubarray(arr){
if(arr.length==1)返回[arr];
否则{
subar=getsubarray(arr.slice(1));
返回subar.concat(subar.map(e=>e.concat(arr[0]),[[arr[0]]);
}
}
console.log(JSON.stringify(getsubrays(arr));
以下是使用ECMAScript 2015查找所有组合的方法:
函数*generateCombinations(arr){
函数*DoGenerateCompositions(偏移、组合){
产量组合;
for(设i=偏移;i }
组合,短组合:
函数组合(数组){
返回新数组(1 Array.filter((e2,j)=>i&1 a.length>=2))
有史以来第一次提交答案!希望对某人有所帮助。我将此用于一个类似的递归解决方案,该解决方案涉及返回数组,我发现方法非常有用
var-arr=[1,2,3,4,5];
函数getAllCombos(arr){
if(arr[0]==未定义)返回[arr]
返回getAllCombos(arr.slice(1)).flatMap(el=>[el.concat(arr[0]),el])
}
console.log(JSON.stringify(getAllCombos(arr));
这可能会也可能不会很好地进行基准测试,但这是另一种方法,而且非常简洁:
const compositions=arr=>arr.reduce((附件,项目)=>{
返回acc.concat(acc.map(x=>[…x,项]);
}, [[]]);
console.log(组合([1,2,3]).filter(a=>a.length>1));
函数组合(数组){
返回新数组(1 Array.filter((e2,j)=>i&1 a.length>=2))
所以基本上你想要幂集,减去那些<2项的集?问题要求的是组合,而不是排列从我的理解来看,排列是唯一的推导所有可能组合的方法。我认为这根本不正确。创建一个相同大小的不同数组,填充布尔值。检查该数组的所有可能性(每个布尔值都经过true或false),并为每个可能性添加每个“true”的对应值。这将创建2^n中的所有组合,但不会创建所有排列。您也没有描述提取组合的过程
// eg. [2,4,5] ==> {[],[2],[4],[5],[2,4],[4,5],[2,5], [2,4,5]}
var a = [2, 4, 5], res = [];
for (var i = 0; i < Math.pow(2, a.length); i++) {
var bin = (i).toString(2), set = [];
bin = new Array((a.length-bin.length)+1).join("0")+bin;
console.log(bin);
for (var j = 0; j < bin.length; j++) {
if (bin[j] === "1") {
set.push(a[j]);
}
}
res.push(set);
}
console.table(res);