【问题标题】:Intersections and Unions in Ruby for sets with repeated elementsRuby 中的交集和联合用于具有重复元素的集合
【发布时间】:2016-10-14 12:07:51
【问题描述】:

我们如何在 Ruby 中为重复元素的集合获取交集和并集。

# given the sets
a = ["A", "B", "B", "C", "D", "D"]
b = ["B", "C", "D", "D", "D", "E"]

# A union function that adds repetitions
union(a, b)
=> ["A", "B", "B", "C", "D", "D", "D", "E"]

# An intersection function that adds repetitions
intersection(a, b)
=> ["B", "C", "D", "D"]

&| 运算符似乎忽略了重复和重复,如文档中所述。

# union without duplicates
a | b
=> ["A", "B", "C", "D", "E"]

# intersections without duplicates
a & b
=> ["B", "C", "D"]

【问题讨论】:

  • “……似乎忽略了重复。”根据 Array 文档,&| 会忽略重复项。
  • 在数学中,集合是不同对象的集合。
  • 我想您想知道如何实现您的方法unionintersection,您需要在其中说。它们与Array#|Array#& 无关,因此不会添加任何内容来引用它们。示例很好,但它们并不能解释您希望方法展示的精确行为。我们可以猜测,但可能是错误的。你需要用文字描述这些行为;例子是次要的。
  • @CarySwoveland 更好?
  • @CarySwoveland 我从没想过这样看。我以为联合的定义是众所周知的,但是这样描述它实际上更容易实现,谢谢!

标签: ruby multiset set-intersection set-union


【解决方案1】:
def union(a,b)
  (a|b).flat_map { |s| [s]*[a.count(s), b.count(s)].max }
end

union(a,b)
  # => ["A", "B", "B", "C", "D", "D", "D", "E"] 

def intersection(a,b)
  (a|b).flat_map { |s| [s]*[a.count(s), b.count(s)].min }
end

intersection(a,b)
  #=> ["B", "C", "D", "D"]

【讨论】:

  • 哇,非常简洁的解决方案!
【解决方案2】:

Cary Swoveland's answer 的基础上,您可以创建一个临时哈希来计算每个数组中每个成员的出现次数:(我已经概括了参数的数量)

def multiplicities(*arrays)
  m = Hash.new { |h, k| h[k] = Array.new(arrays.size, 0) }
  arrays.each_with_index { |ary, idx| ary.each { |x| m[x][idx] += 1 } }
  m
end

multiplicities(a, b)
#=> {"A"=>[1, 0], "B"=>[2, 1], "C"=>[1, 1], "D"=>[2, 3], "E"=>[0, 1]}

实现unionintersection 很简单:

def union(*arrays)
  multiplicities(*arrays).flat_map { |x, m| Array.new(m.max, x) }
end

def intersection(*arrays)
  multiplicities(*arrays).flat_map { |x, m| Array.new(m.min, x) }
end

union(a, b)        #=> ["A", "B", "B", "C", "D", "D", "D", "E"]
intersection(a, b) #=> ["B", "C", "D", "D"]

使用这种方法,每个数组只需要遍历一次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 2013-04-17
    • 2012-01-26
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多