Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 生成阵列的所有唯一组合的最佳方法?_Javascript_Arrays_Recursion - Fatal编程技术网

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个元素的所有组合(数组数组),我们可以这样做:

  • 迭代具有m个元素的所有组合(数组的数组)
  • 对于每个组合(长度为m的阵列),
  • 如果范围对查找下一个索引有效,则遍历范围(包括两端)
    combination[combination.length-1]
    n-1
  • 制作原始数组的副本并将新索引附加到其中。例如
    newCombination=[…组合,newIndex]
    。这是一个包含m+1元素的新组合
  • 将新找到的组合添加到结果中
  • 现在我们已经找到了所有具有m+1元素的组合。它们可用于查找具有m+2元素的所有组合
  • 我们可以这样做,直到找到最后一个包含n个元素的组合

    为了便于上述算法,内部数据结构可以是:

    [
       [[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
    。我想我们需要一个包装纸。