探讨:n个元素中取出m个元素问题

问题

从包含n个元素的集合中取出m个元素,输出所有的m元列表。

根据是否允许元素重复和是否排序,有以下四种情况:

*)不可重复,排序

*)可重复,排序

*)不可重复,不排序(即随机)

*)可重复,不排序


简单算法:

为了简化问题,我们从0~n-1中输出所有的m元子集。(实际上进行index变换后,很容易得到原题的解)

算法大体可以分为两种:递归和迭代。迭代算法实际上可以看成是动态算法的一种。

无论是递归还是迭代,重要的是找到如下等式:

S(i, j) = F[S(i-1, j-1), S(i-1, j), S(i, j-1)]


代码

#!/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

转载于:https://my.oschina.net/u/158589/blog/86916

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值