如何在ruby中进行组合/排列

  • 本文关键字:组合 排列 ruby ruby
  • 更新时间 :
  • 英文 :


我有一个熟悉的问题,看起来像是数学世界的排列/组合。

如何通过ruby实现以下目标?

badges = "1-2-3"
badge_cascade = []
badges.split("-").each do |b|
  badge_cascade << b
end
Gives: => ["1", "2", "3"]
But I want it to be is:
=> ["1", "2", "3", 
  "1-2", "2-3", "3-1", "2-1", "3-2", "1-3", 
  "1-2-3", "2-3-1", "3-1-2"]

功能方法:

bs = "1-2-3".split("-")
strings = 1.upto(bs.size).flat_map do |n| 
  bs.permutation(n).map { |vs| vs.join("-") } 
end
#=> ["1", "2", "3", "1-2", "1-3", "2-1", "2-3", "3-1", "3-2", "1-2-3", "1-3-2", "2-1-3", "2-3-1", "3-1-2", "3-2-1"]

您必须使用Array#排列方法才能获得所有排列:

arr = "1-2-3".split '-' # => ["1", "2", "3"]
res = (1..arr.length).reduce([]) { |res, length|
  res += arr.permutation(length).to_a
}.map {|arr| arr.join('-')}
puts res.inspect
# => ["1", "2", "3", "1-2", "1-3", "2-1", "2-3", "3-1", "3-2", "1-2-3", "1-3-2", "2-1-3", "2-3-1", "3-1-2", "3-2-1"]

让我解释一下代码:

  1. 您通过分隔符'-'将字符串拆分为数组#拆分方法

  2. 你需要所有长度为1、2、3的排列。范围1..arr.length表示所有这些长度。

  3. 您可以使用Enumerable#reduce收集所有排列的数组。你会在这里得到数组:

    [["1"], ["2"], ["3"], ["1", "2"], ["1", "3"], ["2", "1"], ["2", "3"], ["3", "1"], ["3", "2"], ["1", "2", "3"], ["1", "3", "2"], ["2", "1", "3"], ["2", "3", "1"], ["3", "1", "2"], ["3", "2", "1"]]
    
  4. 使用array#join将该数组的所有子数组转换为字符串,并在Enumerable#map 中使用'-'分隔符

Array#permutation(n)将为您提供长度n的所有排列作为数组数组,因此您可以用1到徽章中的位数之间的每个长度来调用它。最后一步是将所有这些映射回用-分隔的字符串。

badges = "1-2-3"
badges_split = badges.split('-')
permutations = []
(1..badges_split.size).each do |n|
    permutations += badges_split.permutation(n).to_a
end
result = permutations.map { |permutation| permutation.join('-') }

更新:我认为Alex使用reduce是一种更优雅的方法,但我现在将把这个答案留在这里,以防有用

最新更新