Python:数学,排列组合,可重复的组合。

1 示例代码

  直接上代码。

def test1():
    """
    有“a/b/c/d/e”五个字符用以组成八位字符串,可完全重复如“aaaaaaaa”,也可部分重复如“aaaabcde”。
    将“aaaabcde”和“bcdeaaaa”、“bacadaea”视作一种组合。问:这样的组合一共有多少种?
    """
    """
    问题定性:可重复的组合。
    首先是个组合问题,因为有些长得虽然不一样但元素相同,也当一种,这肯定是组合而非排列。
    其实,组合中元素可重复。元素就五种,你不重复无论如何也搞不到八位长啊。
    """
    """
    第一种解法:
    直接手写。
    结果:会累死,可能还没结果。放弃。
    """
    """
    第二种解法:
    相当于求 v + w + x + y + z = 8 的非负整数解。
    好像也得枚举?
    """
    """
    第三种解法:
    借助纯排列组合算法:挡板法。
    五个字符先站好。
    你发现没有,其实这五个字符的地位是相同的。
    为啥?
    先不说为啥,再放四个挡板进来,好比这样:
    字符 / 字符 / 字符 / 字符 / 字符 字符 字符 字符
    不是提供了五个字符吗,怎么上边显示八个?
    肯定是某个或某几个字符被重复用了,不然怎么凑够八位长?
    怎么是四个板不是三个也不是五个或者八个?
    我们用这种形式表示最终结果呈现方式,比如:
    a / b / c / d / e e e e
    表示最终结果组成为:1个 a ,1个 b ,1个 c ,1个 d ,4个 e 。这肯定是想要的结果之一。
    这不正好是用五个不同的字符组成了允许元素重复的八位长字符啦?
    所以只能是四个板儿。
    同样,
    a / b / c // e e e e e
    表示最终结果组成为:1个 a ,1个 b ,1个 c ,0个 d ,5个 e 。
    最终还是八位字符,同样满足要求,允许没有 d 哈。这也是想要的结果之一。
    别说没有 d ,题目中都说了,8 个 a 都可以,岂止是没有 d 。
    / b / c / d / e e e e e
    允许最左边或最右边就是板儿,以上表示结果中没有 a 。这也是想要的结果之一。
    你发现没,其实你问有多少种组合,其实就是问八个字符和四个挡板有多少种排列的方法。
    注意是排列,不是组合。
    为啥说是排列?
    / / / /
    // // /
    上边这两种挡板的放法产生的结果肯定不一样哈。
    但挡板和挡板是同等地位的对吧,作用就是把字符隔开,你说把最后一个板儿和第一个板儿换换位置放,结果是一样的。
    现在说字符和字符其实也和板儿一样,也是同等地位,是不是不好容易理解?
    确实。
    我们简化下问题,用两个字符来解释。
    用“a/b”这两个字符组配成长度为四的文本串,这个简单,我们可以穷举:
    先做个模型:(a 的数量, b 的数量)。一共就给了两个字符做原料,要考虑的肯定是几个 a 几个 b ,所以形状元组就两个元素。
    如写:(0, 4),意思就是:0a + 4b,即:bbbb。
    接着来:
    (1, 3):1a + 3b,abbb
    (2, 2):2a + 2b,aabb
    (3, 1):3a + 1b,aaab
    (4, 0):4a + 0b,aaaa
    没了,对吧?就五种。
    如果表示成挡板儿和字符,对应于(3, 1)的可以这样画:
    /b
    咋不写 a ?你想啊,一共就两个字符作为基本元素,现在已经划出来 b 是一个,那你说 a 能是几个?肯定是三个,对吧?
    需要几个挡板儿?一个。
    补全:
    aaa/b
    再划一个:
    aa/
    不用多说了,补全长这样:aa/bb
    你发现没,不管结果长啥样,总可以抽象成:mnp/q。
    如果把 mnpq 的位置固定住,挡板儿的放法也没几种:
    /mnpq
    m/npq
    mn/pq
    mnp/q
    mnpq/
    如果 mnpq 也搞搞全排列呢?我们让 mnpq/ 这五个东西全排列一下:
    5! = 120 种对吧?
    前边说了板儿和板儿其实地位相同,我们去掉板在这 120 种里的重复数:1! = 1。
    这个简单,就一个板儿,所以 120 应该再除以 1 ,当然还是 120 。
    如果是两个板儿,要去的重复数就是 2! = 2 。
    好了,到这里再理解为什么说字符和字符也是同等地位。
    如果是 mn/pq ,代回“a/b”,对应:aabb,是吧?
    这里我们是把 mn 都当成 a ,pq 都当成 b ,对吧?
    行,再看 pq/mn ,在“mnpq/”的全排列中,肯定有这么一个结果,是吧?
    行,我们把这一行的上一行的上一行说的话代入,结果是啥?
    bbaa。
    是不是和 aabb 是一回事儿?因为我们最终求的是可重复的组合,不是排列。
    所以,字符和字符其实地位也是一样的,这话是针对“mnpq/”这个全排列说的。
    那“mnpq/”这个全排列中,其实就两个因素在变化(不就是“ab”?),字符和字符地位相同,挡板儿和挡板儿地位相同。
    那我们就先把这五个家伙全排列,再去掉字符和字符的序,再去掉挡板儿和挡板儿的序。
    5!/4!/1! = 5 。
    简单示例说完,再回到要求的题目上来。
    最终文本串长度为八,提供的字符元素有五个,需要四个挡板儿:
    8!/5!/4! = 495 。
    这就是所求的组合的数量。
    """
    """
    最简单的还是编程实现,不用动脑子。
    管它重复不重复,我穷举出来,再去重,不就行了?
    """
    """
    生成所有可能的 8 位索引序列(0-4 对应 a-e)。
    有五个元素不假,但我让它们可以重复到八位。
    """
    index_combinations = itertools.product(range(5), repeat=8)
    """
    统计每个索引序列对应的字符出现次数
    """
    unique_patterns = set()
    """
    用个集合变量。众所周知,集合的特点是:确切、无序、不重
    """
    for indices in index_combinations:
        """
        将索引转换为字符出现次数(如 [0, 0, 1, 2] → a:2, b:1, c:1)
        """
        char_counts = Counter(indices)
        """
        将次数按字符顺序排序,确保不同排列视为同一组合。
        """
        sorted_counts = tuple(sorted(char_counts.items()))
        unique_patterns.add(sorted_counts)
    print(f"组合总数:{len(unique_patterns)}")
    """
    495
    """
    """
    这是最朴素的算法了,脑子里怎么想的,就怎么写。
    但这样写效率不高。
    下边再展示一种,但不解释了。
    """
    """
    生成所有可能的五元组(每个字符出现次数 0-8),类似:(0, 0, 0, 0, 8)
    """
    total = 0
    for counts in itertools.product(range(9), repeat=5):
        if sum(counts) == 8:
            print(counts)
            total += 1
    print(f"组合总数:{total}")
    """
    495
    """
    """
    想打印出所有的组合?
    """
    for counts in itertools.product(range(9), repeat=5):
        if sum(counts) == 8:
            chars = ['a', 'b', 'c', 'd', 'e']
            distribution = ' + '.join(f"{count}{char}" for count, char in zip(counts, chars) if count > 0)
            print(distribution)
            """
            类似:2a + 3b + 1c + 1d + 1e
            """
# ~ test1()

2 欢迎纠错

  欢迎纠错,随时更新。
  联系方式:评论、私信,或 企鹅 :179 0042 182 。

3 论文写作/Python 学习智能体

https://chatglm.cn/share/WF2C5ree


  • 以下关于 Markdown 编辑器

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

++ 新的改变

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. 全新的界面设计 ,将会带来全新的写作体验;
  2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
  3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
  4. 全新的 KaTeX数学公式 语法;
  5. 增加了支持甘特图的mermaid语法1 功能;
  6. 增加了 多屏幕编辑 Markdown文章功能;
  7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
  8. 增加了 检查列表 功能。

++ 功能快捷键

撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G

++ 合理的创建标题,有助于目录的生成

直接输入1次+,并按下space后,将生成1级标题。
输入2次+,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

++ 如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

++ 插入链接与图片

链接: link.

图片: Alt

带尺寸的图片: Alt

居中的图片: Alt

居中并且带尺寸的图片: Alt

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

++ 如何插入一段漂亮的代码片

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
var foo = 'bar';

++ 生成一个适合你的列表

  • 项目
    • 项目
      • 项目
  1. 项目1
  2. 项目2
  3. 项目3
  • 计划任务
  • 完成任务

++ 创建一个表格
一个简单的表格是这么创建的:

项目Value
电脑$1600
手机$12
导管$1

+++ 设定内容居中、居左、居右
使用:---------:居中
使用:----------居左
使用----------:居右

第一列第二列第三列
第一列文本居中第二列文本居右第三列文本居左

+++ SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPEASCIIHTML
Single backticks'Isn't this fun?'‘Isn’t this fun?’
Quotes"Isn't this fun?"“Isn’t this fun?”
Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

++ 创建一个自定义列表
Markdown
: Text-to-HTML conversion tool

Authors
John
Luke

++ 如何创建一个注脚

一个具有注脚的文本。2

++ 注释也是必不可少的

Markdown将文本转换为 HTML

++ KaTeX数学公式

您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

你可以找到更多关于的信息 LaTeX 数学表达式here.

++ 新的甘特图功能,丰富你的文章

2014-01-07 2014-01-09 2014-01-11 2014-01-13 2014-01-15 2014-01-17 2014-01-19 2014-01-21 已完成 进行中 计划一 计划二 现有任务 Adding GANTT diagram functionality to mermaid
  • 关于 甘特图 语法,参考 这儿,

++ UML 图表

可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:

张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

这将产生一个流程图。:

链接
长方形
圆角长方形
菱形
  • 关于 Mermaid 语法,参考 这儿,

++ FLowchart流程图

我们依旧会支持flowchart的流程图:

Created with Raphaël 2.3.0 开始 我的操作 确认? 结束 yes no
  • 关于 Flowchart流程图 语法,参考 这儿.

++ 导出与导入

+++ 导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

+++ 导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。


  1. mermaid语法说明 ↩︎

  2. 注脚的解释 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值