合并所有组合以获得完整的集合

时间:2019-02-18 16:29:36

标签: ruby algorithm

我有一个数组:

arr = [1, 2, 3]

我想找到所有组合,然后组合这些组合以获得仅包含一次arr所有元素的数组。顺序无关紧要。第一个组合应返回类似

的内容
combis = [
  [1], [2], [3],
  [1, 2], [1, 3], [2, 3], 
  [1, 2, 3]
]

我需要具有valid组合的combis,其中包含arr中的每个值刚好一次。所以:

valid = [
  [[1], [2], [3]],
  [[1], [2, 3]],
  [[2], [1, 3]],
  [[3], [1, 2]],
  [[1, 2, 3]]
]

这个很快就变大了,所以我需要一种方法来做到这一点,而无需两次使用组合功能,然后过滤掉不正确的函数。

我觉得我需要使用某种树结构和递归来生成第二组组合,并在不再是有效的最终组时停止遍历。

如果有人可以帮助我提供(伪)代码,那将是很棒的事情。

1 个答案:

答案 0 :(得分:4)

使用Enumerator::Lazy立即拒绝不需要的/无效的组合:

combis = 1.upto(arr.size).each_with_object([]) do |i, acc|
  acc.concat arr.combination(i).to_a 
end 
#⇒ [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]

valid = 1.upto(arr.size).each_with_object([]) do |i, acc|
  acc.concat(
    #                     ⇓⇓⇓⇓ THIS
    combis.combination(i).lazy.select do |e|
      items = e.flatten
      items.uniq.size == items.size && items | arr == items
    end.to_a
  )
end
#⇒ [[[1, 2, 3]], [[1], [2, 3]], [[2], [1, 3]], [[3], [1, 2]], [[1], [2], [3]]]