繁体   English   中英

在Java中获取具有特定大小的子集的set的powerset

[英]Obtaining the powerset of set with subsets of a certain size in Java

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

谢谢!

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

创建第二个列表,仅包含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;
    }
}

您可以使用简单的回溯来执行此操作。 您只需检查每个元素,然后选择此元素是否在您的子集中。 同时,您可以跟踪您正在尝试构建的当前子集( current_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]
*/

请注意,如果要保留子集,可以将它们插入某个结构(例如List )而不是打印它们。

试试这个来生成集合的幂集:

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);
        }
    }

}

有关更多信息,请访问https://github.com/m-vahidalizadeh/foundations/blob/master/src/algorithms/GeneratePowerSet.java 我希望它有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM