【问题标题】:How to combination/permutation in ruby?如何在红宝石中组合/排列?
【发布时间】:2012-06-20 15:48:36
【问题描述】:

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

如何通过 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"]

【问题讨论】:

  • 3 个元素排列的预期值看起来很奇怪,只有 3 个元素?我数了 6。

标签: ruby


【解决方案1】:

功能方法:

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"]

【讨论】:

    【解决方案2】:

    您需要使用Array#permutation 方法来获取所有排列:

    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. 您将字符串拆分为数组,将分隔符'-' 传递给String#split 方法

    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 中使用'-' 分隔符

    【讨论】:

    • 请注意,您正在模拟现有的抽象 flat_mapreduce+concat
    【解决方案3】:

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

    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 是一种更优雅的方法,但我将把这个答案留在这里,以防它有用。 p>

    【讨论】:

      猜你喜欢
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 1970-01-01
      • 2013-12-01
      相关资源
      最近更新 更多