用公式实现排列组合

wils
wils

创作者俱乐部成员

公式的表达能力越来越强了,原来下意识用宏解决的问题,现在似乎用公式也可以方便的完成,赞赞赞!!!

感觉现在的公式越来越像lisp的方言了,let、lambda的用法似乎可以参考scheme语言的教程。

下面是尝试用公式,做一个从X个数里取Y个的不重复的组合的方法:

遇到的问题:

  • IF这里只能嵌套着写两层,为什么用IFS替换成两个判断会报错?是不是bug啊,谁来帮忙试试

  • map之类的公式会遍历单元格,而不是遍历行,导致用图中这样连接成字符串的方法还简单点,否则不能用map还得再加一层lambda有点不习惯

💡

=LET(f,LAMBDA(x,y,IF(y=1,x,IF(ROWS(x)=y,TEXTJOIN(",",,x),VSTACK(MAP(f(DROP(x,1),y-1),LAMBDA(i,TAKE(x,1)&","&i)),f(DROP(x,1),y))))),f(A1:A6,3))

大概解释一下公式:

  • 总的框架是LET(f,LAMBDA(x,y,IF()),f(x,y)),这是个写递归的套路,用let给lambda表达式一个名称f(这样就不用像Excel那样必须使用名称管理器才能递归),if里先是递归的退出条件

  • 第一层IF,y=1是指,要从数组x里取y个数,如果只取1个,直接返回x就行

  • 第二层IF,ROWS(x)=y是指,如果x的行数等于y,那直接把x用逗号连起来返回就行

  • 剩下的情况需要递归,总的框架是个VSTACK,里面分别是x里的当前行,选中、不选中两种情况

  • 选中当前行,那么在剩下的行里需要选取的个数y就需要减1,这些选出来的行,前头都要加上当前行,MAP(f(DROP(x,1),y-1),LAMBDA(i,TAKE(x,1)&","&i))

  • 不选中当前行,那么就是在剩下的行里再选y个,f(DROP(x,1),y)

  • 把这两条路的结果vstack起来,就是结果

广东省
浏览 525
2
7
分享
7 +1
1
2 +1
全部评论 1
 
亂雲飛渡
写得好
· 广东省
1
回复