Javascript 生成阵列的所有唯一组合的最佳方法?
假设我有这个数组:Javascript 生成阵列的所有唯一组合的最佳方法?,javascript,arrays,recursion,Javascript,Arrays,Recursion,假设我有这个数组: const input = [“a”, “b”, “c”, “d”]; 我要创建此输出: [ [“a”], [“a”, “b”], [“a”, “c”], [“a”, “d”], [“a”, “b”, “c”], [“a”, “b”, “d”], [“a”, “c”, “d”], [“a”, “b”, “c”, “d”], [“b”], [“b”, “c”], [“b”, “d”], [“b”, “c”, “d”], [“
const input = [“a”, “b”, “c”, “d”];
我要创建此输出:
[
[“a”],
[“a”, “b”],
[“a”, “c”],
[“a”, “d”],
[“a”, “b”, “c”],
[“a”, “b”, “d”],
[“a”, “c”, “d”],
[“a”, “b”, “c”, “d”],
[“b”],
[“b”, “c”],
[“b”, “d”],
[“b”, “c”, “d”],
[“c”],
[“c”, “d”],
[“d”]
]
我不关心组合的顺序,也不关心组合的长度,只需要使用各种方法来唯一地组合数组中的项
在JavaScript中实现这一点的最佳方法是什么?我怀疑有一个很好的递归解决方案,但迭代也可以
另外,什么是正确的技术术语?递归解决方案可能是最容易理解的,尽管我猜还有其他更有效的(计算复杂性方面的)解决方案 首先,数组中的实际元素无关紧要,因此我们可以使用它们的索引(0…n-1)进行计算,然后我们通过
actualray=indexArray.map(i=>inputArray[i])
将这些索引转换为实际元素。在下面的讨论中,我们假设索引存储在输出/结果中
然后,由于组合中的顺序并不重要,而且组合中的所有内容(索引)都必须是唯一的,因此我们可以确保组合中的索引始终以递增顺序排列
因此,我们可以从只包含1个元素的组合(数组的数组)开始。没有任何计算,我们都知道这些是:
[[0]、[1]、[2]、[3]、…[n-1]]
。
我们可以编写代码来生成它们,并将它们用作种子
然后,为了根据包含m个元素的已知组合(数组数组)找出包含m+1个元素的所有组合(数组数组),我们可以这样做:
combination[combination.length-1]
和n-1
newCombination=[…组合,newIndex]
。这是一个包含m+1元素的新组合[
[[0], [1], [2], ..., [n-1]], // indexes of combinations with 1 elements
[[0, 1], [0, 2], ..., [n-2, n-1]], // indexes of combinations with 2 elements
...
[[0, 2, ... n-1]], // indexes of combinations with n elements
]
为了验证正确性,我们只需要检查以下各项:
- 组合的总数与我们可以通过数学计算的总数相同
- 在每个组合中,元素总是按递增顺序排列
- 没有重复的组合(添加
到composition.join(“,”)
可能很方便)集合
顺便说一句,这只是我的想法,我还没有用任何真实的代码或数据来验证:-)正确的技术术语是。以下是标准的递归形式:
const f=(A,i=0)=>i==A.length?[[]]:f(A,i+1).flatMap(x=>x[A[i]].concat(x)];
log(JSON.stringify(f(['a','b','c','d']))代码>不,这些不是排列。组合是这里的正确术语。对不起,我看不到这里有任何订购。排列处理顺序,组合处理分组。这也不是笛卡尔积,因为我们处理的是一个列表。OP想要Python的JS版本的[列表(itertools.compositions(“abcd”,i))用于范围(1,5)]
中的i,但要扁平化。在某个地方应该是一个明显的傻瓜,但由于这些术语的混淆,我似乎永远也找不到这类傻瓜。这回答了你的问题吗@戈伦找到了一个。只需将基于最小长度2的过滤更改为最小长度1。我特别喜欢佐维奥对这个问题的回答,回答得很好。应该有一个dupe finder徽章。或者类似地,const powerSet=([x,…xs])=>x==未定义?[[]]:powerSet(xs).flatMap(p=>[p[x,…p]])
@ScottSauyet,这会对原始阵列进行不必要的复制。是的,每件事都有权衡。我的版本牺牲了一些性能来实现更优雅的实现。为了方便使用默认参数,您牺牲了以特定方式调用它的能力(想想[set1,set2,set3].map(f)
)。选项很好。@ScottSauyet哦,对了,你和我以前讨论过默认参数和map
。我想我们需要一个包装纸。