02 - 借玩具的组合
本帖最后由 不二如是 于 2022-4-17 22:22 编辑在线视频:
https://www.bilibili.com/video/BV1HT4y1K7DY?p=4
找到女神的手机号了吗?
小师妹做了什么,让这么多童鞋发弹幕:
哈哈哈,不告诉你们,自己去看啦~
这讲咱们来解决一个借玩具问题,小由鱼到手了 5 个新玩具,准备借给 3 位鱼油,并且一人只能借一个玩具。
请问:
有多少种不同的借法?
这种题目一看就是属于数学中常见的排列组合问题。
抛开题目场景,就是从 5 个数中取 3 个不同数的排列组合的总数。
我们可以将 5 个玩具用 1~5 编号,A、B、C 三个人每次都可以从 5 个玩具中中任选 1 个。
即每人都有 5 种选择,由于 1 个玩具不可能同时借给一个以上的人。
因此只要这三个人所选玩具的编号不同,则即为一次有效的借用次数。
对于每个人所选玩具号,还是采用穷举循环来实现。
即从每个人在玩具号(1、2、3、4、5)范围内进行穷举,从而得到可行的结果。
对于第一个人的选择,可以用循环将其列出,在上一节已经说过,while 循环的优化方案:for ... in range() 。
同理,对于第二个人、第三个人可以用同样的方法。
由于一个玩具只能借给一个人,故第二个人的选择会受到第一个人的限制,最后一个人的选择会受到第二个人的限制。
即后面的选择都是在前面选择的前提下进行的,所以可采用循环的嵌套来解决问题。
利用循环解决问题的时候,其实都会涉及循环三要素。
之前一直只是带大家用,这次来总结下。
何为循环三要素呢?
就是这三件事:
[*]循环变量的初值
[*]循环的控制条件
[*]使循环趋于结束的循环变量值的改变
找到这 3 要素是进行编程的关键。
本题的输出结果有一个条件限制:
**** Hidden Message *****
对于听过师妹小讲堂前几讲的童鞋,将上面条件写成代码应该不难。
一个 if 语句搞定:
if a != b and a != c and c != b
剩下就是不同号码的判断。
最简单粗暴还是穷举法,因为是 3 个人就用 a,b,c 代表。
玩具范围就用数字 1,2,3,4,5 表示。
分别给 a,b,c 赋值来模拟借玩具的过程,初值就都是 1。
使循环趋于结束的循环变量值的改变就是每层 a,b,c 值都要小于 6 。
流程图就是这样:
在上节课的最后教给童鞋们,像这种 while 循环都可以用 for in range() 来实现。
还是那句话:
做好流程图,程序立刻出~
直接撸代码:
# A、B、C三人,5个玩具,每人每次只能借一个
# 用a、b、c分别表示三人所选玩具的编号
if __name__ == "__main__":
print("A, B, C三人所选玩具方案:")
# 用来控制A借玩具编号
for a in range(1, 6):
# 用来控制B借玩具编号
for b in range(1, 6):
# 用来控制C借玩具编号
for c in range(1, 6):
if a != b and a != c and c != b:
print("A: %2dB: %2dC: %2d" % (a, b, c),end='')
print()
来看下结果:
出来是出来了,但是好长好长,看起来很麻烦!
如果还想知道总共有多少个方案,貌似也没办法,难道一个一个去数吗??
怎么可能?!
对于程序员来说:能让机器干的活,绝不自己来哈!
我们可以创建一个变量 i 用来计数,输出方案的时候就加 1。
另外这种计数值还有个作用,就是用来换行!
例如我们想一排显示 4 组数据,就可以判断 i 这个整除 4 是否有余数。
余数为 0 说明是 4 个倍数,就可以来换行,简单修改下代码:
if __name__ == "__main__":
# i用来计数
i = 0
print("A, B, C三人所选玩具方案:")
for a in range(1, 6):
for b in range(1, 6):
for c in range(1, 6):
if a != b and a != c and c != b:
print("A: %2dB: %2dC: %2d" % (a, b, c),end='')
# 输出时i计数加1
i += 1
# 一行4个数据
if i % 4 == 0:
print()
# 采用更符合Python规范的打印
print('共有{}种组合'.format(i))
输出:
本节课的重点除了上面的循环三要素外,另一个就是打印!
代码中的这种打印:
print("A: %2dB: %2dC: %2d" % (a, b, c),end='')
是属于 Python2 遗留下来的 C 语言风格打印方式,在 Python3 中已规定不推荐。
要使用 str.format() 方法:
print('共有{}种组合'.format(i))
小甲鱼老师在最新版的 Python 教程中已讲过,自行学习:
文字版在这里:字符串格式化语法参考
以后再遇到这种组合问题,都是大同小异,不许说不会啦~
这次不拖堂啦,下课!
源码(不推荐下载{:10_334:} ):**** Hidden Message ***** 沙发 我觉得可以用 itertools 学习 {:5_101:} 学习 bool想学C 发表于 2021-4-22 08:05
学习
好好学 k = 0
for x in range(5):
for y in range(5):
for z in range(5):
if x != y and y != z and z != x:
print(f'A: {x}, B: {y}, C: {z}', end = ' ')
k += 1
if k % 4 == 0:
print()
print(f'共有{k}种分法')
count=0
for i in range(5):
for j in range(5):
for z in range(5):
if i != j and j != z and i != z:
count+=1
print(i,j,z,' count:', count) 学习中... {:9_241:} {:5_95:} xixi if __name__ == "__main__":
print("A, B, C三人所选玩具方案:")
# f"A: {a:2d}B: {b:2d}C: {c:2d}" f-string 字符串格式化
# a != b != c != a 如同 a != b and a != c and b != c , {:5_109:} 看看学习学习 if __name__ == "__main__":
这句话的作用是什么?只是为了返回ture,执行下面的语句吗?那不加不是一样吗
for a in range(1,6):
for b in range(1,6):
for c in range(1,6):
if a != b and b != c and a != c:
print(a,b,c) 1
页:
[1]
2