找到数组项的所有组合,数量最多为n,且数组项可以重复。

3
我有一个数组,例如['PP', 'PT', 'CK']。我有一个数字n,例如4。我想生成所有数组项的组合,直到4,因此输出将包含所有组合。
[['PP', 'PP', 'PP', 'PP'],

['PP', 'PP', 'PP', 'PT'],

['PP', 'PP', 'PT', 'PT'],

['PP', 'PT', 'PT', 'PT'],

['PT', 'PT', 'PT', 'PT'],

['PP', 'PP', 'PP', 'CK'],

['PP', 'PP', 'CK', 'CK'],

['PP, 'CK', 'CK', 'CK'],

['CK', 'CK', 'CK', 'CK'],

['PT', 'CK', 'CK', 'PP'],

['PT', 'PT', 'CK', 'PP],

['PT', 'PT', 'PT', 'CK']]

我尝试编写以下代码,但它没有给我期望的输出。

const getCombination = (arr, n) => {
  const list = [];
  if (arr.length === 1) {
    const items = [];
    for (let t = 0; t < n; t++) {
      items.push(arr[0]);
    }
    list.push(items);
    return list;
  }
  for (let i = n; i >= 0; i--) {
    let k = i;
    const items = [];
    while (k > 0) {
      items.push(arr[0]);
      k--;
    }
    if (i === n) {
      list.push(items);
      continue;
    }
    let c = n - i;
    let val = 1;
    if (i === 0) {
      val = 0;
    }
    for (let j = val; j < arr.length; j++) {
      const op = [...items];
      const l = arr[j];
      let p = 0;
      let isRun = false;
      if (j === 0) {
        continue;
      }
      while (p < c && items.length < n) {
        op.push(l);
        p++;
        isRun = true;
      }
      if (isRun) list.push(op);
    }
  }
  return list;
}

console.log("list", getCombination(["PP", "PT", "CK"], 4));


我认为它看起来是正确的。 - Matt
1个回答

3
你可以采用递归的方法,返回一个数组,其中包含剩余计数的最后一项,或者迭代实际元素可能的计数数量。然后将新数组的映射结果推送到结果集中。

Result with unique count of items.

PP PP PP PP
PP PP PP PT
PP PP PP CK
PP PP PT PT
PP PP PT CK
PP PP CK CK
PP PT PT PT
PP PT PT CK
PP PT CK CK
PP CK CK CK
PT PT PT PT
PT PT PT CK
PT PT CK CK
PT CK CK CK
CK CK CK CK

const
    getCombinations = ([item, ...array], n) => {
        if (!array.length) return [Array(n).fill(item)];

        const result = [];
        let m = n;

        do {
            const left = Array(m).fill(item);
            result.push(...getCombinations(array, n - m)
                .map(right => [...left, ...right])
            );
        } while (m--);

        return result;
    },
    result = getCombinations(["PP", "PT", "CK"], 4);

result.forEach(a => console.log(...a));
.as-console-wrapper { max-height: 100% !important; top: 0; }


感谢您的干净明了的回答。我遇到了这样的问题:我得到了像[['CT','CT','CT','PT'],['CT','PT','CT','CT']]这样的项目。在这里,我已经有3个CT和1个PT,所以我不想要第二个项目。有没有简单的方法来过滤它?顺序不重要。如果我已经有3个CT和1个PT,那么它就不应该以不同的顺序被包括进去。 - aman
1
@aman,请查看编辑。它可以不经过过滤就能运行。 - Nina Scholz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接