组合

来源:互联网 发布:思科网络系统 编辑:程序博客网 时间:2024/04/29 21:02

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]*ndef 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
原创粉丝点击