我正在尝试编写一个可以枚举一组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而没有一般性。
谢谢!
答案 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);
}
}
这是快速的脏实现,所以可能它错过了一些案例,但它通常用至少一个工作案例来证明这个想法。