我需要从一个包含7个对象的集合中获取所有可能的5个对象的组合。组合不允许重复(选择顺序无关,因此选择相同的对象但以不同的顺序选出来的组合被视为相同的组合)。
我已经有了实现,它运行正常并且能够产生正确的结果:
String[] vegetablesSet = {"Pepper", "Cabbage", "Tomato", "Carrot", "Beans", "Cucumber", "Peas"};
final int SALAD_COMBINATION_SIZE = 5; // Example: {"Tomato", "Cabbage", "Cucumber", "Pepper", "Carrot"}
Set<Set<String>> allSaladCombinations = new HashSet<>();
for (int i = 1, max = 1 << vegetablesSet.length; i < max; i++) {
Set<String> set = new HashSet<>();
int count = 0;
for (int j = 0, k = 1; j < vegetablesSet.length; j++, k <<= 1) {
if ((k & i) != 0) {
set.add(vegetablesSet[j]);
count++;
}
}
if (count == SALAD_COMBINATION_SIZE) {
allSaladCombinations.add(set);
}
}
for (Set<String> set : allSaladCombinations) {
for (String vegatable : set) {
System.out.print(vegatable + " ");
}
System.out.println();
}
输出结果正确:已找到21个正确的组合。
但是它使用了位运算符,在我的评估中不太可读、可维护和可扩展。我想将其重构或完全重写为更灵活和易于理解的面向对象方法。我非常想知道如何使用OOP和递归完成这个任务。
在我的项目中,我没有使用Google Guava
、Apache Commons
或CombinatoricsLib
。而且我不想为一个方法包含整个第三方库。我在该网站上搜索类似的问题,但只找到了一个很好的清晰的排列实现:https://stackoverflow.com/a/14486955
这些情况具有类似的含义,但是对象的顺序对我来说并不重要,在我的情况下,它们被认为是相同的组合,不应计算在内。