🎯 WPS 递归 | 排列:N 选 M 排列问题一键搞定!!!
这一期我们学习解析排列递归的内涵方法!
一、效果展示
输入编码、取个数,1 个公式自动生成所有排列组合,无需 VBA,纯函数实现!
编码 | 取个数 | 总组合数 | 自动生成排列 |
ABCDEF | 6 | 720 种 | 自动列出所有排列 |
二、核心公式
excel
=LET(TT,LAMBDA(a,b,c,
IF(LEN(TAKE(b,1))=c,b,
LET(
x,REGEXP(a,"."),
y,TOCOL(IF(ISNUMBER(FIND(x,b,1)),SB,b&x),3),
TT(a,y,c)))),
TT(D4,"",F4))
三、公式逐行拆解
1. 外层 LET 定义递归函数
excel
=LET(TT, LAMBDA(a,b,c, ... ), TT(D4,"",F4))
LET:给公式起别名,简化递归调用,避免重复写长函数名
LAMBDA:定义自定义递归函数TT,3 个核心参数:
a:原始编码(D4 单元格,如ABCDEF,全程不变)
b:当前正在拼接的排列字符串(递归过程中动态变化)
c:目标取个数(F4 单元格,如6,全程不变)
最后一行TT(D4,"",F4):递归启动入口,初始b为空字符串,开始第一轮计算
2. 递归终止条件
excel
IF(LEN(TAKE(b,1))=c, b, ... )
逻辑:判断当前拼接的字符串长度LEN(TAKE(b,1))是否等于目标取个数c
✅ 满足条件:直接返回当前排列b,本轮递归结束,该排列进入最终结果
❌ 不满足:进入下一轮递归,继续拼接字符
补充:TAKE(b,1)是为了兼容b为数组的场景,确保取到单个字符串的长度
3. 递归核心逻辑(运行过程明细)
excel
LET(
x,REGEXP(a,"."),
y,TOCOL(IF(ISNUMBER(FIND(x,b,1)),SB,b&x),3),
TT(a,y,c)
)
我们以 ** 编码ABC、取个数2** 为例,完整拆解每一步的运行过程:
🔹 第 1 轮递归(初始调用:TT("ABC", "", 2))
当前b = "",长度0 ≠ 2,进入递归
x = REGEXP("ABC", "."):用正则拆分原始编码,得到单个字符数组 {"A","B","C"}
FIND(x, b, 1):检查每个字符是否在b(空字符串)中,结果为 {#VALUE!,#VALUE!,#VALUE!}(空字符串找不到任何字符)
ISNUMBER(...):判断是否为数字,结果为 {FALSE,FALSE,FALSE}
IF(...,SB,b&x):条件为FALSE,执行b&x,得到 {"A","B","C"}
y = TOCOL(...,3):过滤空值(本次无空值),最终y = {"A","B","C"}
递归调用:TT("ABC", {"A","B","C"}, 2),进入第 2 轮
🔹 第 2 轮递归(分支 1:TT("ABC", "A", 2))
当前b = "A",长度1 ≠ 2,进入递归
x = REGEXP("ABC", ".") = {"A","B","C"}
FIND(x, "A", 1):检查字符是否在"A"中,结果为 {1,#VALUE!,#VALUE!}
ISNUMBER(...):结果为 {TRUE,FALSE,FALSE}
IF(...,SB,b&x):A已存在返回SB,B/C不存在,得到 {SB,"AB","AC"}
y = TOCOL(...,3):过滤空值,最终y = {"AB","AC"}
递归调用:TT("ABC", {"AB","AC"}, 2),进入第 3 轮
🔹 第 3 轮递归(分支 1-1:TT("ABC", "AB", 2))
当前b = "AB",长度2 = 2,触发终止条件
直接返回"AB",该排列进入最终结果,本轮递归结束
🔹 第 3 轮递归(分支 1-2:TT("ABC", "AC", 2))
当前b = "AC",长度2 = 2,触发终止条件
直接返回"AC",该排列进入最终结果,本轮递归结束
🔹 第 2 轮递归(分支 2:TT("ABC", "B", 2))
逻辑完全一致,最终生成{"BA","BC"},触发终止条件后返回结果
🔹 第 2 轮递归(分支 3:TT("ABC", "C", 2))
逻辑完全一致,最终生成{"CA","CB"},触发终止条件后返回结果
🔹 最终结果汇总
所有满足条件的排列自动溢出:{"AB","AC","BA","BC","CA","CB"},共3×2=6种,完全符合排列计算逻辑
四、使用步骤(3 步上手)
填参数:
D4 单元格:输入原始编码(如ABCDEF、12345,不能有重复字符)
F4 单元格:输入取个数(如6,代表 6 选 6 全排列;3代表 6 选 3 排列,不能大于编码长度)
输公式:在 A5 单元格粘贴上面的完整公式,按回车
出结果:WPS 自动溢出所有排列组合,无需下拉填充
五、关键知识点 & 避坑指南
✅ 适用版本
WPS 365 / WPS 2021 及以上版本(支持LAMBDA、LET、REGEXP、TOCOL等动态数组函数)
不支持 Excel 2019 及以下版本
✅ 核心原理
递归思想:通过LAMBDA函数实现自我调用,逐步拼接字符,直到达到目标长度
去重逻辑:用FIND判断字符是否已使用,避免重复排列
动态数组:用TOCOL自动处理数组,实现一键溢出
⚠️ 避坑提示
原始编码不能有重复字符,否则会生成重复排列
取个数c不能大于原始编码长度LEN(D4),否则无结果
全排列计算量随N指数级增长:6! = 720、7! = 5040、8! = 40320,不建议计算N≥10的全排列,会卡顿
若公式报错,检查 WPS 版本,更新到最新版即可
六、拓展用法
1. 6 选 3 排列(非全排列)
编码:ABCDEF,取个数:3
公式不变,自动生成6×5×4=120种排列
2. 数字 / 符号排列
编码:1234,取个数:4,自动生成 4 位数字全排列
编码:甲乙丙丁,取个数:2,自动生成 2 字组合排列
3. 批量生成抽奖序号
编码:0123456789,取个数:4,自动生成所有 4 位不重复抽奖序号
七、总结
这个公式完美解决了 WPS 中N 选 M 排列组合的生成难题,用纯函数替代了复杂的 VBA 宏,适合办公自动化、数据整理、抽奖分组等场景。核心就是LAMBDA递归 + 动态数组,学会这个思路,还能拓展出组合、笛卡尔积等更多高阶玩法!