分区数组

我正在努力编写一个算法来将数组转换为该数组的所有可能的排列,但它们必须是内联/连续的。 示例如下:

阵:

['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) 

这将生成输入数组的每个可能排列的每个可能的分组。 不过,我不太确定你正在寻找什么。