Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中获取具有一定大小子集的集合的幂集_Java_Algorithm_Set_Big O - Fatal编程技术网

在Java中获取具有一定大小子集的集合的幂集

在Java中获取具有一定大小子集的集合的幂集,java,algorithm,set,big-o,Java,Algorithm,Set,Big O,我试图找到一种有效的方法来生成具有特定大小k的子集的集的幂集。我已经找到了如何生成所有功率集和一个范围内的功率集的答案,但我不确定如果我只想要一个特定大小的功率集,我会怎么做 谢谢 创建一个包含集合元素的列表 创建仅由1和0组成的第二个列表,其中 列表中的元素总数等于集合中的元素数 列表中1的数量等于k 对于第二个列表的每个排列,子集由第一个列表中的元素组成,其在第二个列表中的对应条目为1。这通过将集合转换为列表并迭代所有可能的索引组合来实现 static <E> Set<

我试图找到一种有效的方法来生成具有特定大小k的子集的集的幂集。我已经找到了如何生成所有功率集和一个范围内的功率集的答案,但我不确定如果我只想要一个特定大小的功率集,我会怎么做


谢谢

创建一个包含集合元素的列表

创建仅由1和0组成的第二个列表,其中

  • 列表中的元素总数等于集合中的元素数
  • 列表中1的数量等于
    k

对于第二个列表的每个排列,子集由第一个列表中的元素组成,其在第二个列表中的对应条目为1。

这通过将集合转换为列表并迭代所有可能的索引组合来实现

static <E> Set<Set<E>> subsets(Set<E> set, int n) {
    if (n < 0)
        throw new IllegalArgumentException();
    Set<Set<E>> temp = new HashSet<>();
    int size = set.size();
    if (n > size)
        return temp;
    List<E> list = new ArrayList<>(set);
    int[] indices = new int[n];
    for (int i = 0; i < n; i++)
        indices[i] = i;
    while (true) {
        Set<E> s = new HashSet<>();
        for (int i : indices)
            s.add(list.get(i));
        temp.add(s);
        int r = n - 1;
        for (int m = size; r >= 0 && indices[r] == --m; r--);
        if (r == -1)
            return temp;
        for (int c = indices[r]; r < n;)
            indices[r++] = ++c;
    }
}
静态集合子集(集合集合,int n){
if(n<0)
抛出新的IllegalArgumentException();
Set temp=new HashSet();
int size=set.size();
如果(n>大小)
返回温度;
列表=新的ArrayList(集合);
int[]索引=新的int[n];
对于(int i=0;i=0&&index[r]=--m;r--);
如果(r==-1)
返回温度;
对于(int c=指数[r];r
您可以使用简单的回溯来完成此操作。您只需检查每个元素,然后选择该元素是否在您的子集中。同时,您可以跟踪您正在尝试构建的当前子集(
current\u subset
)以及您仍然可以选择的元素数量(
k
)。示例实现:

static <E> void backtrack(int index, int k, Deque<E> current_subset,
                          List<E> elements) 
{
    if (k == 0) {
        System.out.println(current_subset);
        return;
    }
    if (index == elements.size())
        return;
    current_subset.push(elements.get(index));
    backtrack(index + 1, k - 1, current_subset, elements);
    current_subset.pop();
    backtrack(index + 1, k, current_subset, elements);
}

backtrack(0, 2, new ArrayDeque<Integer>(), 
          Arrays.asList(new Integer[]{0, 1, 2, 3, 4}));
/*
[1, 0]
[2, 0]
[3, 0]
[4, 0]
[2, 1]
[3, 1]
[4, 1]
[3, 2]
[4, 2]
*/
static void backtrack(int index,int k,Deque current_子集,
列表元素)
{
如果(k==0){
System.out.println(当前_子集);
返回;
}
if(index==elements.size())
返回;
当前_subset.push(elements.get(index));
回溯(索引+1,k-1,当前_子集,元素);
当前_subset.pop();
回溯(索引+1,k,当前_子集,元素);
}
回溯(0,2,新的ArrayQue(),
asList(新整数[]{0,1,2,3,4});
/*
[1, 0]
[2, 0]
[3, 0]
[4, 0]
[2, 1]
[3, 1]
[4, 1]
[3, 2]
[4, 2]
*/

请注意,如果要保留子集,只需将其插入某些结构(如
列表
)中,而不必打印它们。

尝试此操作以生成集合的功率集:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class GeneratePowerSet {

    public static <T> Set<Set<T>> powerSet(Set<T> originalSet) {
        Set<Set<T>> sets = new HashSet<>();
        if (originalSet.isEmpty()) {
            sets.add(new HashSet<T>());
            return sets;
        }
        List<T> list = new ArrayList<>(originalSet);
        T head = list.get(0);
        Set<T> rest = new HashSet<>(list.subList(1, list.size()));
        for (Set<T> set : powerSet(rest)) {
            Set<T> newSet = new HashSet<>();
            newSet.add(head);
            newSet.addAll(set);
            sets.add(newSet);
            sets.add(set);
        }
        return sets;
    }

    public static void main(String args[]) {
        Set<Integer> mySet = new HashSet<Integer>();
        mySet.add(1);
        mySet.add(2);
        mySet.add(3);
        mySet.add(4);
        for (Set<Integer> s : powerSet(mySet)) {
            System.out.println(s);
        }
    }

}
import java.util.ArrayList;
导入java.util.HashSet;
导入java.util.List;
导入java.util.Set;
公共类GeneratePowerSet{
公用静态设置电源集(设置原始设置){
Set Set=新的HashSet();
if(originalSet.isEmpty()){
add(newhashset());
返回集;
}
列表列表=新的ArrayList(originalSet);
T head=list.get(0);
Set rest=newhashset(list.subList(1,list.size());
用于(组:动力组(其余)){
Set newSet=newhashset();
新闻集添加(标题);
newSet.addAll(集合);
添加(新闻集);
集合。添加(集合);
}
返回集;
}
公共静态void main(字符串参数[]){
Set mySet=newhashset();
mySet.add(1);
mySet.add(2);
mySet.add(3);
mySet.add(4);
用于(集合s:powerSet(mySet)){
系统输出打印项次;
}
}
}

有关更多信息,请访问。我希望有帮助

你有没有试过这么做?也许你的实现效率很低?这个集合有多少元素?@Sesame,我目前使用的方法是生成整个功率集,然后迭代并删除与我想要的长度不匹配的子集。通常情况下的“公式”是
2^S=flatte([[x U Y代表Y in 2^(S-{x})]代表x in S])
。您需要大小为
n
的子集,因此希望每个
Y
的大小为
n-1
。因此,只需使用一个现有的实现,向函数中添加一个额外的size参数,并在递归调用时使用
size-1
。@user3386109,该集合包含2到31个元素。我想生成长度为3的子集。不是置换,而是组合。集合中的元素没有顺序。@有人创建一个列表,而不是集合,并计算列表的所有排列。基础数据结构不相关。您需要大小为
k
的所有组合,而不是排列。例如,集合{x,y}只有一个子集大小为2。你的方法会返回两个子集,就好像{x,y}和{y,x}是不相等的。@someguy,我想我们对置换的定义有分歧。例如,我将
{0,1,1}的置换定义为{{0,1,1},{1,0,1},{1,1,0}
请参阅,以获得一种不重复计算数组置换的方法。对于置换的定义不能有任何分歧。这是一个数学概念!你的例子是有缺陷的,因为“集合”实际上不是集合。元素必须是唯一的。如果是,你会发现实际上有6种不同的排列。然而,正如我所说,我们感兴趣的是不同的组合,而不是排列。请阅读以下小条目:。这是基本集合论/概率论。