我有一个数组:
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]]
]
这个很快就变大了,所以我需要一种方法来做到这一点,而无需两次使用组合功能,然后过滤掉不正确的函数。
我觉得我需要使用某种树结构和递归来生成第二组组合,并在不再是有效的最终组时停止遍历。
如果有人可以帮助我提供(伪)代码,那将是很棒的事情。
答案 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]]]