Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 613|回复: 0

python解决组合问题

[复制链接]
  • TA的每日心情
    奋斗
    6 天前
  • 签到天数: 803 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726482
    发表于 2021-4-12 11:23:13 | 显示全部楼层 |阅读模式

    1.问题描述

     比如9个数中取4个数的组合以及列出各种组合,该如何做?

     我们可以考虑以下一个简单组合:从1,2,3,4,5,6中,如何选取任意四个数的组合。

     固定:1   2  3  ,组合有1234 1235 1236 

     固定1 2 4,组合有:1245 1246

     固定1 2 5,组合有:1256

        固定1 3 4,组合有:1345 1346

     固定1 3 5,组合有:1356

     固定1 4 5,组合有:1456

     固定2 3 4,组合有:2345 2346

     固定2 3 5,组合有:2356

     固定2 4 5,组合有:2456

     固定3 4 5,组合有:3456

      共有15种组合

    2.简单实现一下组合算法

      首先,我们分析上面列出的10个步骤,对于1),很明显,在固定了1 2 3这三个数之后,第四个数就是4、5、6三个数进行了循环(还记得循环吗,计算机最拿手的就是做循环)。其次,我们再分析1)2)3)这三个步骤中固定的数字,前两个没有变,都是1 2,只是第三个数在进行循环(又是循环)。

      通过分析,我们可以找到这样的规律:

        1    先固定3个数,让第四个数进行循环

        2    让第三个数循环,重复第一步

        3    让第二个数循环,重复第一步

        4    让第一个数循环,重复第一步

    def combNumberLoop4(m, b):
        totalNumber = 0
        for i in range(1, m+2-4):
            b[0] = i
            for j in range(i+1, m+2-3):
                b[1] = j
                for k in range(j+1, m+2-2):
                    b[2] = k
                    for l in range(k+1, m+2-1):
                        b[3] = l
                        print b
                        totalNumber += 1
        return totalNumber
    
     
    group=[99,99,99,99]
    print "\nUsing Loop: %d\n" % combNumberLoop4(6, group)

      程序的输出结果,正如之前分析的那样。

    3.如何递归解决组合问题

      我们再回到C(6,4)问题,除了上面列出的十个步骤,我们换个思路:

        如果在6个数中选定一个数,那么确定剩下的3个数是不是变为了“从5个数中选3个数的组合问题”了呢?以此类推,这似乎变成了一个“递归”问题了,确实,我们可以用递归的思路来解决这个问题。

        对于C(m, n)列出所有组合的问题,可以按照一下的步骤来进行编程,这次我们按从后往前的顺序来列出所有组合:

          1   选定一个元素i,在范围[m, n]内进行循环

          2   将i 作为所求组合的最后一个元素

          3   如果n-1>0,进行递归调用,求C(m-1, n-1);否则,输出结果

          4   重复①

        注意,设计递归函数一定要有终止条件,否则会造成“死循环”。

    实现的代码如下:

    def combNumber(m, n, b):
        global totalNumberR
        for i in range(m, n-1, -1):   
            b[n-1] = i
            if n-1>0:
                combNumber(i-1,n-1,b)
            else:
                print b
                totalNumberR += 1
        return totalNumberR
    
     
    
    group=[99,99,99,99,99]
    totalNumberR = 0
    print "\nUsing Recursive: %d\n" % combNumber(7,5,group) 

      递归的使用,让程序写起来非常的简洁,但是,在写程序的时候,我有两个地方(其实程序也就难在这两个地方),折腾了好几天才弄清楚:

         首先是for循环的循环范围如何确定;

         其次是递归调用时使用的参数设计;

    3.python提供的内置组合函数

    def combinations_with_replacement(iterable, r):
        # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
        pool = tuple(iterable)
        n = len(pool)
        if not n and r:
            return
        indices = [0] * r
        yield tuple(pool for i in indices)
        while True:
            for i in reversed(range(r)):
                if indices != n - 1:
                    break
            else:
                return
            indices[i:] = [indices + 1] * (r - i)
            yield tuple(pool for i in indices)

    4.更多组合算法

      请点击我:https://docs.python.org/3/library/itertools.html?highlight=combinations#itertools.combinations

     

      

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-11-23 20:57 , Processed in 0.059668 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表