Java實現集合的組合(從組合中取出K個元素進行組合的所有情況)
阿新 • • 發佈:2019-02-15
1.利用遞迴進行取出資料:
public static <T> List<List<T>> combinations(List<T> list, int k) {
if (k == 0 || list.isEmpty()) {//去除K大於list.size的情況。即取出長度不足K時清除此list
return Collections.emptyList();
}
if (k == 1) {//遞迴呼叫最後分成的都是1個1個的,從這裡面取出元素
return list.stream().map(e -> Stream.of(e).collect(toList())).collect(toList());
}
Map<Boolean, List<T>> headAndTail = split(list, 1);
List<T> head = headAndTail.get(true);
List<T> tail = headAndTail.get(false);
List<List<T>> c1 = combinations(tail, (k - 1)).stream().map(e -> {
List<T> l = new ArrayList<>();
l.addAll(head);
l.addAll(e);
return l;
}).collect(Collectors.toList());
List<List<T>> c2 = combinations(tail, k);
c1.addAll(c2);
return c1;
}
/**
*根據n將集合分成兩組
**/
public static <T> Map<Boolean, List<T>> split(List<T> list, int n) {
return IntStream
.range(0, list.size())
.mapToObj(i -> new SimpleEntry<>(i, list.get(i)))
.collect(partitioningBy(entry -> entry.getKey() < n, mapping(SimpleEntry::getValue, toList())));
}
2.測試用例如下:
@Test
public void shouldFindAllCombinationsOfSize2FromAListWithSize3() throws Exception {
List<String> input = Stream.of("a", "b", "c").collect(toList());
List<List<String>> combinations = P26.combinations(input, 2);
System.out.println("2-->"+combinations.toString());
assertThat(combinations, hasSize(3));
}
3.測試結果如下:
2-->[[a, b], [a, c], [b, c]]