排列组合 A(n, m) 字典序

针对数字序列[1, 2, 3, 4, 5], 常见的排列组合情况有:

1. 求n个数的全排列,要求各个排列升序.[1,2,3,4,5] ... [5,4,3,2,1]

2. 求A(m, n),结果为升序.   [1,2,3] .... [5,4,3]

3. 求组合C(m, n), 结果为升序.[1,2,3] ... [3,4,5]

4. 求{1, 2, 3, 4, 5, 6}的所有子集.

 

方法:

 

使用递归法:

针对求全排列,可以通过递归求全排列,但是结果不是升序。

针对求子集,递归地取/或不取某元素,结果也不是长序。

 

使用二进制法:

对0-2^m-1,每个数字对应一个子集。

 

使用字典序法:

针对全排列,使用next_permutation(),即一个排列,从最后一个元素向前,找到升序的元素,将其与后面比其稍大的元素交换,并将其后的子串逆序,即找到了下一个排列。

针对组合,使用下标增长的方法。初始下标为[0, 1, 2],其下一个下标则为[0, 1, 3], ..., [0, 1, 4], [0, 2, 3], ....[2, 3, 4].

针对A(5, 3),可以使用改进的next_permutation()方法,将next_permutation的"从最后一个元素向前"改为从第3个元素向前来处理。

 

这两天刚关注了python,就用它来写个小程序吧。

下面是用 python 写的 A(n, m) 的算法:

#!/usr/bin/python

# filename: permutation.py


def permutation(n, m):
    global l
    ret = 0
    while ret == 0:
        print( l[0:m] )
        ret = next_permutation(m)
#        raw_input('###')
   

 

def next_permutation(m):
    global l
    n = len(l)
#    print( 'n:', n )
    change_indx = -1;
    exchange_indx = -1;
    for i in range(m-1, -1, -1):
        if change_indx > 0:
            break
        min_value = n+1;
        for j in range(i+1, n):
            if l[j] > l[i] and l[j]<min_value:
                change_indx = i;
                exchange_indx = j
                min_value = l[j]
    if change_indx < 0:
        print (' no change_indx. ')
        return -1
#    print( 'change_indx:', change_indx, exchange_indx, change_indx )
    bigger_indx = exchange_indx
    tmp = l[change_indx]
    l[change_indx] = l[bigger_indx]
    l[bigger_indx] = tmp


    pre_l = l[0:change_indx+1]
    end_l = l[change_indx+1:len(l)]
    end_l.sort()
    l = pre_l + end_l

#    print('pre_l:', pre_l)
#   print('end_l:', end_l)
    return 0

 

if __name__ == '__main__':
    print ( __name__ )
    l = [1, 2, 3, 4, 5]
    permutation(len(l), 3)

 

运行结果如下

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值