zoukankan      html  css  js  c++  java
  • Python练习题 017:三支乒乓球队出赛名单

    【Python练习题 017】 两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比。请编程序找出三队赛手的名单。

    ------------------------------------------------------

    这题真真想破我脑袋了,看了好几份别人的代码才勉强看懂,真是…… 一开始我只想着先把所有可能都配出来(ax, ay, az, bx, by, bz, cx, cy, cz),然后根据后面的条件排除不可能的配对。怎么写也写不对。

    后来看了别人的代码,结合自己的思考,整理出基本思路如下:假设a,b,c的对手分别是i,j,k,将i,j,k所有可能出现的组合先穷举出来,同时需要满足2个条件:i,j,k不能同时出现(即a,b,c的对手不可能有重复);a不对x,c不对x,z,只要满足此2条件就可以。简而言之:用3个for穷举,用2个if限定条件。代码如下:

    for i in range(ord('x'), ord('z')+1):  #假设a,b,c的对手分别是i,j,k
        for j in range(ord('x'), ord('z')+1):  #用3个for穷举i,j,k可能出现的所有组合
            for k in range(ord('x'), ord('z')+1):
                if i != j and j != k and k != i:  #条件1:i,j,k不能同时出现
                    if i != ord('x') and k != ord('x') and k != ord('z'):  #条件2:a不对x,c不对x,z
                        print('a vs %s, b vs %s, c vs %s' % (chr(i), chr(j), chr(k)))
    

    输出结果如下:

    a vs z, b vs x, c vs y

    根据上述代码,联想到之前 求解不重复的3位数 时用到的itertools库,觉得可以简化代码如下:

    import itertools
    
    for i in itertools.permutations('xyz'):
        if i[0] != 'x' and i[2] != 'x' and i[2] != 'z':
            print('a vs %s, b vs %s, c vs %s' % (i[0], i[1], i[2]))
    

    输出结果一样。代码简洁很多,结构也清晰不少。

    itertools.permutations()是个好东西,可以直接将'xyz'生成包含所有排列的列表。另外两个相关的库方法分别是:itertools.product()生成笛卡尔数列(即包括所有排列方式,itertools.combinations()生成所有组合的列表。就生成项的数目而言,product() > permutations() > combinations()。本题中,permutations('xyz', 3)可生成6组排列方式,而如果换成combinations('xyz', 3),则只有1种组合方式('x', 'y', 'z')。详见官方文档

    【2016-10-17 更新】----------------------------------------------------

    感谢 rm-rf 的耐心解答,又多了一种解题思路:先将 a,b,c 这一队列出所有可能的排列方式(共6组),然后每一组都跟 x,y,z 进行匹配(用zip()方法),并设置判断条件。事实证明,这6组之中,只有1组是满足条件的。代码如下:

    import itertools
    
    team_1 = ['a', 'b', 'c']
    team_2 = ['x', 'y', 'z']
    
    for i in itertools.permutations(team_1, 3):
        for j in zip(i, team_2):
            if j in [('a','x'),('c','x'),('c','z')]:
                break
        else:
            print(i, team_2)
    

    输出结果如下:

    ('b', 'c', 'a') ['x', 'y', 'z']

    rm-rf 还提供了另一种写法,但是……好吧,还没学到 lambda,自定义函数也还没怎么学,所以根本看不懂…… 但还是很感谢啊!希望过不了多久,我就能看懂了~~~

    import itertools
    
    check_list = [('a', 'x'), ('c', 'x'), ('c', 'z')]
    for i in itertools.permutations(team_1, 3):
        f = lambda a,b: len([True for j in zip(a, b) if j not in check_list])
        if f(i, team_2) == 3:
            print(i, team_2)
    

     

    ++++++++++++++++++++++++++++++++++++++

    题目出处:编程语言入门经典100例【Python版】

  • 相关阅读:
    数据库生成说明
    Android 的 SurfaceView 双缓冲应用
    一些and知识 和ui
    weibo11
    android总结
    weibo14
    weibo9
    weibo12
    weibo10
    在线人数的统计
  • 原文地址:https://www.cnblogs.com/iderek/p/5967808.html
Copyright © 2011-2022 走看看