递归算法之排列组合-求一个集合S的m个元素的组合和所有可能的组合情况

  求一个集合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 }

 

posted on 2019-05-07 17:54  Burkut  阅读(1119)  评论(0编辑  收藏  举报