🎯 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))

注:SB 为 错误值,等同于NA#,TOCOL忽略

三、公式逐行拆解

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,进入递归

  1. x = REGEXP("ABC", "."):用正则拆分原始编码,得到单个字符数组 {"A","B","C"}

  1. FIND(x, b, 1):检查每个字符是否在b(空字符串)中,结果为 {#VALUE!,#VALUE!,#VALUE!}(空字符串找不到任何字符)

  1. ISNUMBER(...):判断是否为数字,结果为 {FALSE,FALSE,FALSE}

  1. IF(...,SB,b&x):条件为FALSE,执行b&x,得到 {"A","B","C"}

  1. y = TOCOL(...,3):过滤空值(本次无空值),最终y = {"A","B","C"}

  1. 递归调用:TT("ABC", {"A","B","C"}, 2),进入第 2 轮

🔹 第 2 轮递归(分支 1:TT("ABC", "A", 2)

  • 当前b = "A",长度1 ≠ 2,进入递归

  1. x = REGEXP("ABC", ".") = {"A","B","C"}

  1. FIND(x, "A", 1):检查字符是否在"A"中,结果为 {1,#VALUE!,#VALUE!}

  1. ISNUMBER(...):结果为 {TRUE,FALSE,FALSE}

  1. IF(...,SB,b&x)A已存在返回SBB/C不存在,得到 {SB,"AB","AC"}

  1. y = TOCOL(...,3):过滤空值,最终y = {"AB","AC"}

  1. 递归调用: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 步上手)

  1. 填参数

  • D4 单元格:输入原始编码(如ABCDEF12345不能有重复字符

  • F4 单元格:输入取个数(如6,代表 6 选 6 全排列;3代表 6 选 3 排列,不能大于编码长度)

  1. 输公式:在 A5 单元格粘贴上面的完整公式,按回车

  1. 出结果:WPS 自动溢出所有排列组合,无需下拉填充


五、关键知识点 & 避坑指南

适用版本

  • WPS 365 / WPS 2021 及以上版本(支持LAMBDALETREGEXPTOCOL等动态数组函数)

  • 不支持 Excel 2019 及以下版本

核心原理

  • 递归思想:通过LAMBDA函数实现自我调用,逐步拼接字符,直到达到目标长度

  • 去重逻辑:用FIND判断字符是否已使用,避免重复排列

  • 动态数组:用TOCOL自动处理数组,实现一键溢出

⚠️ 避坑提示

  1. 原始编码不能有重复字符,否则会生成重复排列

  1. 取个数c不能大于原始编码长度LEN(D4),否则无结果

  1. 全排列计算量随N指数级增长:6! = 7207! = 50408! = 40320,不建议计算N≥10的全排列,会卡顿

  1. 若公式报错,检查 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递归 + 动态数组,学会这个思路,还能拓展出组合、笛卡尔积等更多高阶玩法!

浙江省
浏览 184
1
6
分享
6 +1
1 +1
全部评论