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编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
- 全新的界面设计 ,将会带来全新的写作体验;
- 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
- 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
- 全新的 KaTeX数学公式 语法;
- 增加了支持甘特图的mermaid语法1 功能;
- 增加了 多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
++ 功能快捷键
撤销: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.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
++ 如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
// An highlighted block
var foo = 'bar';
++ 生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
++ 创建一个表格
一个简单的表格是这么创建的:
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
+++ 设定内容居中、居左、居右
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
+++ SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
TYPE | ASCII | HTML |
---|---|---|
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)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
++ 新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
++ UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
++ FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
++ 导出与导入
+++ 导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
+++ 导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎