枚举set Java / Groovy的n项组合

时间:2015-07-17 19:20:18

标签: java recursion groovy

我正在尝试编写一个可以枚举一组N个元素的所有组合的操作。换句话说,N是未知的并且取决于用户输入。在接收N时,该函数应该能够给出N项集合的所有可能组合,以及来自集合U的所有元素。比如,U = {A,B,C ... J},10个元素在总。 我需要的另一个例子,函数枚举(3)应该告诉我所有可能的组合,如{A,B,C},{A,D,J}等,使用从U中挑选的元素。

我尝试以一种使用for循环的方式执行此操作(初始化整数,因为在这种情况下U的大小恰好为10,因此我可以使用123来表示{A,B,C} ...)。但代码闻起来很糟糕,我想知道如何使用递归调用更优雅。

Java / Groovy都是可以接受的(因为我也在尝试它们)。如果有人能够提供有关如何使用Groovy中的闭包来实现这一点的想法,那将会更受欢迎。

另外请不要像我一样使用整数来表示组合,因为我认为这只适用于某个U而没有一般性。

谢谢!

1 个答案:

答案 0 :(得分:1)

我相信我有解决方案。

import java.util.HashSet;
import java.util.Set;

public class Generator<T> {
    Set<T> source;
    Set<Set<T>> combinations;

    public Generator(Set<T> source) {
        this.source = source;
    }

    public static void main(String[] args) {
        final Set<String> source = new HashSet<>();
        for (char character = 'A'; character <= 'Z'; character++){
            source.add(String.valueOf(character));
        }

        final Generator<String> stringGenerator = new Generator<>(source);
        stringGenerator.generate(3);
    }

    public void generate(int size){
        if (size == 0){
            return;
        }
        Set<Set<T>> newCombinations = new HashSet<>();
        for (T element : source) {
            if (combinations == null || combinations.isEmpty()){
                final HashSet<T> set = new HashSet<>();
                set.add(element);
                newCombinations.add(set);
            } else {
                for (Set<T> combination : combinations) {
                    final HashSet<T> newCombination = new HashSet<>(combination);
                    if (newCombination.add(element)) {
                        newCombinations.add(newCombination);
                    }
                }
            }
        }
        combinations = newCombinations;
        generate(size - 1);
    }
}

这是快速的脏实现,所以可能它错过了一些案例,但它通常用至少一个工作案例来证明这个想法。