【问题标题】:Find all partitions into sets of a size 2 in javascript在javascript中将所有分区查找为大小为2的集合
【发布时间】:2014-09-12 07:14:45
【问题描述】:

我正在尝试编写一个执行以下操作的函数:

> partitions([a,b,c,d])

< [
  [[a,b],[c,d]],
  [[a,c],[b,d]],
  [[a,d],[b,c]]
  ]

即它找到所有大小为 2 的分区。

目前我正在尝试以递归方式执行此操作:在每次调用时生成一个对列表,并且对于生成的每一对,在列表中再次调用该方法并删除该对。这有效,但会产生重复项。删除重复项需要比较生成的分区中的每个元素,这非常慢。

我想知道是否有更聪明的方法来做到这一点。

【问题讨论】:

  • 我认为可以做到这一点的另一种方法是生成所有在循环移位之前唯一的排列,然后按索引对结果进行分组。是否有一种有效的方法来生成所有不循环相关的排列(无需通过蛮力删除循环排列)?

标签: javascript algorithm recursion set partition


【解决方案1】:

只需获取所有项目的组合并过滤掉所有不需要的,就像这样

function getTwoCombinations(array) {
    var i, j, result = [];
    for (i = 0; i < array.length; i += 1) {
        for (j = i + 1; j < array.length; j += 1) {
            result.push([array[i], array[j]]);
        }
    }
    return result;
}

var result = getTwoCombinations(getTwoCombinations(["a", "b", "c", "d"])).
    filter(function(items) {
        return items[0].every(function(item) {
            return !(items[1].indexOf(item) + 1);
        });
    });

console.log(result);

输出

[ [ [ 'a', 'b' ], [ 'c', 'd' ] ],
  [ [ 'a', 'c' ], [ 'b', 'd' ] ],
  [ [ 'a', 'd' ], [ 'b', 'c' ] ] ]

【讨论】:

  • 谢谢,这很简单。不知何故,我说服自己这样做会很慢,但显然不是这样,所以谢谢。
  • 虽然有问题,但似乎这不适用于超过 4 个元素的任何东西。
  • 我们需要将 getTwoCombinations 推广到构造任意数量的配对,getNCombinations,并将 getTwoCombinations(getTwoCombinations(...)) 替换为 getNCombinations(getTwoCombinations(...),N),其中 N很容易从列表大小确定。
【解决方案2】:

一个好的策略是:

从头到尾

  1. 锁定一个元素(第一个元素)

    1.1 迭代下一个元素(直到结束的第二个)并创建对

  2. 锁定下一个元素(第二个元素)

    2.1 遍历下一个元素(第三个直到结束)并创建对

3...重复直到最后一个元素

视觉帮助:

[a, ]
  [a, b]
  [a, c]
  [a, d]

[b, ]
  [b, c]
  [b, d]

[c, ]
  [c, d]

【讨论】:

  • 那只是生成所有组合,而不是分区,不是吗?
  • 如果列表是有序的,它也会返回分区,这不是正确的吗?
  • 按什么排序?当然,分区将是您在此处生成的这些东西的子集,但是如何对它们进行分组很明显吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
相关资源
最近更新 更多