【发布时间】:2019-12-16 06:02:56
【问题描述】:
我需要从 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
这些情况的含义有些相似,但对象的顺序对我来说并不重要,在我的情况下,它们被认为是相同的组合,不应计算。
【问题讨论】:
-
这不是真正的 OOP 问题;这是一个算法问题,您只需要为其编写一个方法。有关示例,请参见其他问题:stackoverflow.com/questions/11945682/…
-
此解决方案中还使用了位运算符
-
stackoverflow.com/questions/127704/… 中的大量算法可能适合您。
标签: java algorithm oop java-8 combinatorics