问题描述 

小明有5本新书,要借给A、B、C三位小朋友,若每人每次只能借1本,则可以有多少种不同的借法?

分析

该问题是典型的排列组合问题,但是有顺序的要求,比如同样是三人借出了第1、2、3本书,则A、B、C借1、2、3与C、B、A借1、2、3是两组不一样的借法。因为数据量足够小(5本书,3个人),完全可以使用穷举。

可以预见,我们需要设定三层循环,用来模拟不同的借书场景。如果A先借的话,则A可以在5本书中任选一本,也就是有5种选择,而B则只能在剩下的4本书里选,当B选好书后,C只能在剩下的3本书里选择。虽然通过简单的计算,就可以计算出,总共有

Python怎么用从穷举法编程 python穷举法列举_开发语言

种不同的借法。但是通过计算机穷举出所有的借书场景,才是计算机思维的体现:

books = set(range(1,6))
res = []
for a in books:
    for b in books-{a}:
        for c in books-{a,b}:
            res.append((a,b,c))
            print(f"A借第{a}本书,B借第{b}本书,C借第{c}本书")
print(f"共有{len(res)}种借法")

这里我们可以用数字1到5表示第几本书,而可借的书是一个集合,所以,当A借走一本书后,B所能借的集合就是原有的集合减去A所借的书,所以这里可以使用集合的减法,生成一个新的集合。同理,当C借书的时候,可用的书的集合就是原来的集合减去A和B借走的书。这样,我们就可以做到完全遍历。

但是众所周知,Python的优点在于它的海量函数与模块,作为解释型的脚本语言,其不需要学习者过多地关注底层的C实现,于是,往往在C和其他语言中需要多条语句实现的功能,用Python的一句话就可以清晰明了地解决。所以问哥认为,立志将Python作为解决问题的主要手段的学习者,更多地应该是关注结合数学、实现手段、解决问题的创造力。一句话,不要重复造轮子。

就拿本题来说,对于排列组合,Python已经在内置模块itertools中做好了combinations()和permutations()函数,使用内置函数,一句话就可以得出结果,从而不必再去考虑多重循环了。

from itertools import permutations

res = list(permutations(range(1,6),3))
for i in res:
    print(f"A借第{i[0]}本书,B借第{i[1]}本书,C借第{i[2]}本书")
print(f"共有{len(res)}种借法")

输出

A借第1本书,B借第2本书,C借第3本书
A借第1本书,B借第2本书,C借第4本书
A借第1本书,B借第2本书,C借第5本书
A借第1本书,B借第3本书,C借第2本书
A借第1本书,B借第3本书,C借第4本书
A借第1本书,B借第3本书,C借第5本书
A借第1本书,B借第4本书,C借第2本书
A借第1本书,B借第4本书,C借第3本书
A借第1本书,B借第4本书,C借第5本书
A借第1本书,B借第5本书,C借第2本书
A借第1本书,B借第5本书,C借第3本书
A借第1本书,B借第5本书,C借第4本书
A借第2本书,B借第1本书,C借第3本书
A借第2本书,B借第1本书,C借第4本书
A借第2本书,B借第1本书,C借第5本书
A借第2本书,B借第3本书,C借第1本书
A借第2本书,B借第3本书,C借第4本书
A借第2本书,B借第3本书,C借第5本书
A借第2本书,B借第4本书,C借第1本书
A借第2本书,B借第4本书,C借第3本书
A借第2本书,B借第4本书,C借第5本书
A借第2本书,B借第5本书,C借第1本书
A借第2本书,B借第5本书,C借第3本书
A借第2本书,B借第5本书,C借第4本书
A借第3本书,B借第1本书,C借第2本书
A借第3本书,B借第1本书,C借第4本书
A借第3本书,B借第1本书,C借第5本书
A借第3本书,B借第2本书,C借第1本书
A借第3本书,B借第2本书,C借第4本书
A借第3本书,B借第2本书,C借第5本书
A借第3本书,B借第4本书,C借第1本书
A借第3本书,B借第4本书,C借第2本书
A借第3本书,B借第4本书,C借第5本书
A借第3本书,B借第5本书,C借第1本书
A借第3本书,B借第5本书,C借第2本书
A借第3本书,B借第5本书,C借第4本书
A借第4本书,B借第1本书,C借第2本书
A借第4本书,B借第1本书,C借第3本书
A借第4本书,B借第1本书,C借第5本书
A借第4本书,B借第2本书,C借第1本书
A借第4本书,B借第2本书,C借第3本书
A借第4本书,B借第2本书,C借第5本书
A借第4本书,B借第3本书,C借第1本书
A借第4本书,B借第3本书,C借第2本书
A借第4本书,B借第3本书,C借第5本书
A借第4本书,B借第5本书,C借第1本书
A借第4本书,B借第5本书,C借第2本书
A借第4本书,B借第5本书,C借第3本书
A借第5本书,B借第1本书,C借第2本书
A借第5本书,B借第1本书,C借第3本书
A借第5本书,B借第1本书,C借第4本书
A借第5本书,B借第2本书,C借第1本书
A借第5本书,B借第2本书,C借第3本书
A借第5本书,B借第2本书,C借第4本书
A借第5本书,B借第3本书,C借第1本书
A借第5本书,B借第3本书,C借第2本书
A借第5本书,B借第3本书,C借第4本书
A借第5本书,B借第4本书,C借第1本书
A借第5本书,B借第4本书,C借第2本书
A借第5本书,B借第4本书,C借第3本书
共有60种借法