求一个集合S的m个元素组合的所有情况,并打印出来,非常适合采用递归的思路进行求解。因为集合的公式,本身就是递归推导的:
C(n,m) = C(n-1,m-1) + C(n-1,m)。
根据该公式,每次递归会分裂为两次递归,直至m=1或m=n的情况,打印出当前组合情况。
本文实现了给定m的递归代码,并且给出了求一个集合S所有可能的组合的情况,具体可参考下面代码。
核心代码为_fill 函数,往数组 cm 中填充,打印。
1 void combine<E>(Set<E> s, int m) { 2 if (m > 0 && m <= s.length) _fill(List<E>(m), s, 0, m); 3 } 4 5 void combineAll<E>(Set<E> s) { 6 for (var i = 1; i <= s.length; i++) combine(s, i); 7 } 8 9 void _fill<E>(List<E> cm, Set<E> a, int i, int m) { 10 if (m < a.length) { 11 cm[i] = a.first; 12 if (m > 1) { 13 _fill(cm, _rest(a, a.first), i + 1, m - 1); 14 } else { 15 print(cm); 16 } 17 _fill(cm, _rest(a, a.first), i, m); 18 } else { 19 for (var e in a) cm[i++] = e; 20 print(cm); 21 } 22 } 23 24 Set _rest<E>(Set<E> a, E e) { 25 var tmp = a.toSet(); 26 tmp.remove(e); 27 return tmp; 28 }
递归算法之排列组合-求一个集合S的m个元素的组合和所有可能的组合情况
原文:https://www.cnblogs.com/outerspace/p/10827029.html