鱼C-小师妹 发表于 2021-3-5 18:44:52

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 *****

qiuyouzhi 发表于 2021-3-5 18:49:16

沙发

永恒的蓝色梦想 发表于 2021-3-5 19:47:35

我觉得可以用 itertools

hrp 发表于 2021-3-5 19:51:18

学习

yuedong 发表于 2021-3-5 19:59:39

{:5_101:}

bool想学C 发表于 2021-4-22 08:05:36

学习

鱼C-小师妹 发表于 2021-4-22 16:12:14

bool想学C 发表于 2021-4-22 08:05
学习

好好学

zhangyuesd 发表于 2021-6-21 11:33:01

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}种分法')

mzxmzx 发表于 2021-7-6 20:24:14

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)

newdaxie 发表于 2021-7-18 11:11:10

学习中...

天天今天要健身 发表于 2021-8-13 10:15:31

{:9_241:}

hornwong 发表于 2021-8-13 10:24:57

{:5_95:}

kkkkcy 发表于 2021-10-13 12:29:40

xixi

傻眼貓咪 发表于 2021-10-13 13:06:57

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

giegie666 发表于 2021-10-13 15:03:47

kcyyyy 发表于 2021-10-21 11:35:22

{:5_109:}

specail 发表于 2021-10-21 18:16:47

看看学习学习

specail 发表于 2021-10-21 18:21:46

if __name__ == "__main__":
这句话的作用是什么?只是为了返回ture,执行下面的语句吗?那不加不是一样吗

游刃鱿鱼 发表于 2021-11-5 17:20:29


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)

1518355722 发表于 2021-11-21 14:50:03

1
页: [1] 2
查看完整版本: 02 - 借玩具的组合