组合

1. 递归回溯

      在n个元素中选择m个,对于每个元素来说都可以有选择与不选择两种状态,很容易构造一个高度为n的状态数。
s = raw_input('enter n, m:').split()
n,m = int(s[0]),int(s[1])

data = [i for i in range(n)]
sel = [0]*n

def print_comb(data,sel,n):
    for i in range(n):
        if sel[i]==1:
            print data[i],
    print ''


def comb_dfs(data, sel, n, m, cur=0):
    if m==0:
        print_comb(data,sel,n)
        return
    if cur>=n or m < 0:
        return
    #选
    sel[cur] = 1
    comb_dfs(data,sel,n,m-1,cur+1)
    #不选
    sel[cur] = 0
    comb_dfs(data,sel,n,m,cur+1)

2. 非递归--字典序

      对于['a', 'b', 'c', 'd']选择3个元素,它有6种结果,1表示选择,0表示不选择,并把01序列看成2进制数,则结果为:
1100,ab,3(高位在后)
1010,ac,5
0110,bc,6
1001,ad,9
0101,bd,10
0011,cd,12
可以看出每个组合构成了一个有序的序列,初始序列是优先选择左边的元素,即把3个1放到最左边。终止条件是所有的1放到右边,如0111。问题是给定任意一个组合,如何得到它的下一个组合。比如给定0110(bc),得到1001(ad)的步骤为:
1. 从左往右扫描,找到第一个10,将1的位置记录为q,将10反转,得0101
2. 将0到q-1序列里面的1全部提到最左边,得1001。
def comb(data,n,m):
    sel = [1]*m
    for i in range(m,n):
        sel.append(0)

    print_comb(data,sel,n)

    while True:
        one_zero_ids = -1
        one_nums = 0
        for i in range(n):
            if sel[i] == 1:
                one_nums += 1
                one_zero_ids = i
            elif sel[i] == 0 and one_zero_ids != -1:
                break
        if one_zero_ids == -1 or one_zero_ids == n-1:
            break

        sel[one_zero_ids],sel[one_zero_ids+1] = sel[one_zero_ids+1],sel[one_zero_ids]
        
        for i in range(one_nums-1):
            sel[i] = 1
        for i in range(one_nums-1,one_zero_ids):
            sel[i] = 0
            
        print_comb(data,sel,n)      





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值