取小球问题

来源:互联网 发布:php api接口管理系统 编辑:程序博客网 时间:2024/05/17 09:03

盒子里N个小球,每个小球有不相同的编号。从里面取出M个小球,有取出顺序要求。求解有多少情况

def pick(a,n,L=()):    for x in a:        if x not in L:            if len(L)==n-1:                yield (x,)            else:                for res in pick(a,n,L+(x,)):                    yield (x,)+res

比如5个小球,取3个。带入后结果为:

a=[1,2,3,4,5]
print list(pick(a,3))

[(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 2), (1, 3, 4), (1, 3, 5), (1, 4, 2), (1, 4, 3), (1, 4, 5), (1, 5, 2), (1, 5, 3), (1, 5, 4), (2, 1, 3), (2, 1, 4), (2, 1, 5), (2, 3, 1), (2, 3, 4), (2, 3, 5), (2, 4, 1), (2, 4, 3), (2, 4, 5), (2, 5, 1), (2, 5, 3), (2, 5, 4), (3, 1, 2), (3, 1, 4), (3, 1, 5), (3, 2, 1), (3, 2, 4), (3, 2, 5), (3, 4, 1), (3, 4, 2), (3, 4, 5), (3, 5, 1), (3, 5, 2), (3, 5, 4), (4, 1, 2), (4, 1, 3), (4, 1, 5), (4, 2, 1), (4, 2, 3), (4, 2, 5), (4, 3, 1), (4, 3, 2), (4, 3, 5), (4, 5, 1), (4, 5, 2), (4, 5, 3), (5, 1, 2), (5, 1, 3), (5, 1, 4), (5, 2, 1), (5, 2, 3), (5, 2, 4), (5, 3, 1), (5, 3, 2), (5, 3, 4), (5, 4, 1), (5, 4, 2), (5, 4, 3)]


这里参考之前的八皇后写法,用L保留已取出小球。

每取出一个小球,检查跟已取出小球是否重复。不重复的小球则判断,已取出小球数量是否为n-1个:

是:则取出的小球为最后一个,将这个小球编号返回迭代

否:则将递归取球操作,递归时将已取出小球带入递归前置条件 L+(x,) 直至已取出小球数量达到倒数第二个。然后从后往前迭代出完整结果

在函数中加入打印信息后看看

# -*- coding: cp936 -*-def pick(a,n,L=()):    for x in a:        #print '进入迭代:pick(a,%d,%s)' % (n,str(L))        if x not in L:            print 'x取:%d' % x            print '进入迭代:pick(a,%d,%s)' % (n,str(L))            print 'L=%s' % str(L)            if len(L)==n-1:                yield (x,)            else:                for res in pick(a,n,L+(x,)):                    print 'res=%s,反馈结果:%s' % (str(res),str((x,)+res))                    yield (x,)+res        else:            print 'x取%d,L=%s,取值失败' % (x,str(L))a=[1,2,3]print list(pick(a,3))

部分结果为:
x取:1
进入迭代:pick(a,3,())
L=()
x取1,L=(1,),取值失败
x取:2
进入迭代:pick(a,3,(1,))
L=(1,)
x取1,L=(1, 2),取值失败
x取2,L=(1, 2),取值失败
x取:3
进入迭代:pick(a,3,(1, 2))
L=(1, 2)
res=(3,),反馈结果:(2, 3)
res=(2, 3),反馈结果:(1, 2, 3)

可以看出:
1. 首次X取1,进入迭代pick(a,3,())。由于L个数不足2,进行递归pick(a,3,(1,)),此时 (x,)+res 中的 (x,)为(1,)
2.在递归函数 pick(a,3,(1,)) 中,X再次取1失败,X取2。由于L个数不足2,进入递归pick(a,3,(1,2)),此时 (x,)+res 中的 (x,)为(2,)
3.在递归函数 pick(a,3,(1,2))中,X取1,2失败,X取3。由于L个数为2,迭代结果为 3。返回上一层函数pick(a,3,(1,)) , res取值(3,),由于(x,)的值为(2,),所以(x,)+res 的结果为(2,3)
4.将结果再返回上一层函数pick(a,3,()),res取值为(2,3),由于由于(x,)的值为(1,),所以(x,)+res 的结果为(1,2,3)
                                             
0 0
原创粉丝点击