分区数组
我正在努力编写一个算法来将数组转换为该数组的所有可能的排列,但它们必须是内联/连续的。 示例如下:
阵:
['a', 'b', 'c', 'd', 'e', 'f']
结果将是:
[['a'], ['b', 'c', 'd', 'e', 'f']] [['a', 'b'], ['c', 'd', 'e', 'f']] [['a', 'b'], ['c', 'd'], ['e', 'f']] ...
Array#permutations
创建排列,但它们不是有序的。
任何帮助表示赞赏。
a = ['a', 'b', 'c', 'd', 'e', 'f'] (0...a.length) .flat_map{|i| (1...a.length).to_a.combination(i).to_a} .map{|cut| i = -1; a.slice_before{cut.include?(i +=1)}.to_a}
正如我理解你的问题(这与其他人理解它的方式不同),你想要数组的每个可能的分组(分区),其中数组的各个元素(字符)保持其顺序(总是'a'
,然后'b'
,然后'c'
,…… 'f'
)。 我看到这是一个获取每个分区大小的有序列表的问题。
也就是说,我首先将您的三个示例分区表示为:
[[1, 5], [2, 4], [2, 2, 2], ...]
所以我先生成:
[[6], [1, 5], [2, 4], [3, 3] ...]
然后使用它来生成最终结果。
我生成大小的方式非常低效。 这是我想到的第一件事,它适用于您的arrays,但如果它需要处理更大的arrays,则需要更好的算法。 (sawa现在提供了一种更短,更有效的解决方案。)
def sizes(n) (1..n).each_with_object([]) do |i, sizes| sizes.concat (1..n).to_a.repeated_permutation(i).select{|a| a.reduce(:+) == n} end end def partitions_of(a) sizes(a.size).each_with_object([]) do |sizes, results| dup = a.dup results << sizes.each_with_object([]) do |size, result| result << dup.shift(size) end end end
使用你的数组,这个:
partitions_of(['a', 'b', 'c', 'd', 'e', 'f'])
产生这个:
[[["a", "b", "c", "d", "e", "f"]], [["a"], ["b", "c", "d", "e", "f"]], [["a", "b"], ["c", "d", "e", "f"]], [["a", "b", "c"], ["d", "e", "f"]], [["a", "b", "c", "d"], ["e", "f"]], [["a", "b", "c", "d", "e"], ["f"]], [["a"], ["b"], ["c", "d", "e", "f"]], [["a"], ["b", "c"], ["d", "e", "f"]], [["a"], ["b", "c", "d"], ["e", "f"]], [["a"], ["b", "c", "d", "e"], ["f"]], [["a", "b"], ["c"], ["d", "e", "f"]], [["a", "b"], ["c", "d"], ["e", "f"]], [["a", "b"], ["c", "d", "e"], ["f"]], [["a", "b", "c"], ["d"], ["e", "f"]], [["a", "b", "c"], ["d", "e"], ["f"]], [["a", "b", "c", "d"], ["e"], ["f"]], [["a"], ["b"], ["c"], ["d", "e", "f"]], [["a"], ["b"], ["c", "d"], ["e", "f"]], [["a"], ["b"], ["c", "d", "e"], ["f"]], [["a"], ["b", "c"], ["d"], ["e", "f"]], [["a"], ["b", "c"], ["d", "e"], ["f"]], [["a"], ["b", "c", "d"], ["e"], ["f"]], [["a", "b"], ["c"], ["d"], ["e", "f"]], [["a", "b"], ["c"], ["d", "e"], ["f"]], [["a", "b"], ["c", "d"], ["e"], ["f"]], [["a", "b", "c"], ["d"], ["e"], ["f"]], [["a"], ["b"], ["c"], ["d"], ["e", "f"]], [["a"], ["b"], ["c"], ["d", "e"], ["f"]], [["a"], ["b"], ["c", "d"], ["e"], ["f"]], [["a"], ["b", "c"], ["d"], ["e"], ["f"]], [["a", "b"], ["c"], ["d"], ["e"], ["f"]], [["a"], ["b"], ["c"], ["d"], ["e"], ["f"]]]
如果我理解正确的话,那正是你所追求的。
如果您想要所有可能的数组排列组合,那么您可以生成排列,然后生成它们的切片:
array = %w(abcdef) r = array.permutation(array.length).map {|perm| perm.length.times.map {|i| perm.each_slice(i+1).to_a } }.flatten(1)
这将生成输入数组的每个可能排列的每个可能的分组。 不过,我不太确定你正在寻找什么。