從包含n個元素的集合中取出m個元素,輸出全部的m元列表。 python
根據是否容許元素重複和是否排序,有如下四種狀況: 算法
*)不可重複,排序 app
*)可重複,排序 post
*)不可重複,不排序(即隨機) spa
*)可重複,不排序 .net
爲了簡化問題,咱們從0~n-1中輸出全部的m元子集。(實際上進行index變換後,很容易獲得原題的解) code
算法大致能夠分爲兩種:遞歸和迭代。迭代算法實際上能夠當作是動態算法的一種。 排序
不管是遞歸仍是迭代,重要的是找到以下等式: 遞歸
S(i, j) = F[S(i-1, j-1), S(i-1, j), S(i, j-1)] element
#!/usr/bin/env python import sys def getAllSubsets(n, m): ''' get all m-element subset from 0~n-1 no duplicates, sorted ''' # pre: 0<=m<=n # post: all subsets got if m<0 or m>n: print 'invalid args, prog exit' sys.exit(1) if m==0: return [[]] if m==n: return [[i for i in range(0, n)]] subset1 = getAllSubsets(n-1, m) subset2 = getAllSubsets(n-1, m-1) for L in subset2: L.append(n-1) return subset2+subset1 def getAllSubsets2(n, m): ''' get m-element subset from 0~n-1 allow duplicates, sorted ''' # pre: 0<=m # post: all subsets got if m<0: print 'invalid args, prog exit' sys.exit(1) if m==0: return [[]] if n==1: return [[0 for i in range(0, m)]] subset1 = getAllSubsets2(n-1, m) subset2 = getAllSubsets2(n, m-1) for L in subset2: L.append(n-1) return subset2+subset1 def getAllSubsets3(n, m): ''' get m-ele subset from 0~n-1 no duplicates, unsorted ''' # pre: 0<=m<=n if m<0 or m>n: print 'invalid args, prog exit' sys.exit(1) if m==0: return [[]] elif m<=n: subset = getAllSubsets3(n, m-1) subset_ret = [] for i in range(0, n): for s in subset: if i not in s: s_tmp = s[:] s_tmp.append(i) subset_ret.append(s_tmp) return subset_ret def getAllSubsets4(n, m): ''' get m-ele subset from 0~n-1 allow duplicates, unsorted ''' # pre: 0<=m if m<0 or n<1: print 'invalid args, prog exit' sys.exit(1) if m==0: return [[]] else: subset = getAllSubsets4(n, m-1) subset_ret = [] for i in range(0, n): for s in subset: s_tmp = s[:] s_tmp.append(i) subset_ret.append(s_tmp) return subset_ret def getSubs(n, m, flag=1): print 'n=%s, m=%s' % (n,m) if flag==1: # no duplicates, sorted LL = getAllSubsets(n, m) elif flag==2: # allow duplicates, sorted LL = getAllSubsets2(n, m) elif flag==3: # no duplicates, unsorted LL = getAllSubsets3(n, m) elif flag==4: # allow duplicates, unsorted LL = getAllSubsets4(n, m) for L in LL: print L, '\t', print print len(LL) return if __name__ == '__main__': getSubs(4, 2, int(sys.argv[1]))
chenqi@chenqi-laptop ~/MyPro/Algorithms/set-operations $ ./get_all_subsets.py 1 n=4, m=2 [2, 3] [1, 3] [0, 3] [1, 2] [0, 2] [0, 1] 6 chenqi@chenqi-laptop ~/MyPro/Algorithms/set-operations $ ./get_all_subsets.py 2 n=4, m=2 [3, 3] [2, 3] [1, 3] [0, 3] [2, 2] [1, 2] [0, 2] [1, 1] [0, 1] [0, 0] 10 chenqi@chenqi-laptop ~/MyPro/Algorithms/set-operations $ ./get_all_subsets.py 3 n=4, m=2 [1, 0] [2, 0] [3, 0] [0, 1] [2, 1] [3, 1] [0, 2] [1, 2] [3, 2] [0, 3] [1, 3] [2, 3] 12 chenqi@chenqi-laptop ~/MyPro/Algorithms/set-operations $ ./get_all_subsets.py 4 n=4, m=2 [0, 0] [1, 0] [2, 0] [3, 0] [0, 1] [1, 1] [2, 1] [3, 1] [0, 2] [1, 2] [2, 2] [3, 2] [0, 3] [1, 3] [2, 3] [3, \ 3] 16 參考連接:http://www.oschina.net/question/817257_76793