Ruby 使用二维数组中的最大元素数查找非空交点

Ruby 使用二维数组中的最大元素数查找非空交点,ruby,algorithm,intersection,Ruby,Algorithm,Intersection,我有一个二维数组: keys = [[:reference], [:parent_ref, :kind], [:kind, :parent_ref, :reference], [:parent_ref, :kind, :status]] 假设我想要所有这些数组的交集。我可以做到: keys.reduce{|arr, acc| arr & acc} 这将导致[],因为没有通用公共密钥。 现在让我们假设我想使用数组中的最大元素数找到一个“非空交集”。

我有一个二维数组:

   keys = [[:reference],
     [:parent_ref, :kind],
     [:kind, :parent_ref, :reference],
     [:parent_ref, :kind, :status]]
假设我想要所有这些数组的交集。我可以做到:

keys.reduce{|arr, acc| arr & acc}
这将导致[],因为没有通用公共密钥。 现在让我们假设我想使用数组中的最大元素数找到一个“非空交集”。 例如,使用此“方法”的交点将是[:parent_ref,:kind],因为它是

[[:parent_ref, :kind],
         [:kind, :parent_ref, :reference],
         [:parent_ref, :kind, :status]]
我们只需要把
[:reference]
放在一边


您将如何处理/创建这样的算法。

使用置换的暴力:

keys.combination(2).map { |a, b| a & b }.max_by(&:size)
#=> [:parent_ref, :kind]
查找使用的元素,以及暴力:

res = [:parent_ref, :kind]
keys.select { |e| e.sort & res.sort == res.sort }
#=> [[:parent_ref, :kind], [:kind, :parent_ref, :reference], [:parent_ref, :kind, :status]]

假设二维数组是一个字符串数组,其中每个字符串都是一个字符数组。 假设我们有字符串:

CDB
BC
CBA
FDE
EDBC
首先,按递增顺序对每个字符串进行排序

BCD
BC
ABC
DEF
BCDE
然后对字符串进行排序

ABC
BC
BCD
BCDE
DEF

对于每个元素,查找在连续字符串的最长序列中出现的元素。在我们的示例中,是B和C。它们的连续字符串是具有非空交叉点的字符串的最大数目。

我相信您的问题与此相关

为了便于阅读,您可以将输入转换为较短的名称:

matrix = [[:a], [:b, :c], [:c, :b, :a], [:b, :c, :d]]
您可以迭代这些值,并保留一个包含每个值所在的所有集合的哈希:

matrix.each.with_index(1) do |row, i|
  row.each do |value|
    grouped_values[value] << i
  end
end

p grouped_values
# => {:a=>[1, 3], :b=>[2, 3, 4], :c=>[2, 3, 4], :d=>[4]}
因此,集合1和集合3的交集是
[:a]
,集合2、3和集合4的交集是
[:b,:c]

最后,可以选择集合最多或元素最多的交点

arr = [
  [:reference],
  [:parent_ref, :kind],
  [:kind, :parent_ref, :reference],
  [:parent_ref, :kind],
  [:parent_ref, :kind, :status],
  [:kind, :parent_ref, :kind]
]
注意,我修改了示例中给出的
,以包含两种类型的重复项

require 'set'

h = arr.each_with_object(Hash.new { |h,k| h[k] = [] }) { |a,h| h[a.to_set] << a }
  #=> {#<Set: {:reference}>=>[[:reference]],
  #    #<Set: {:parent_ref, :kind}>=>[[:parent_ref, :kind],
  #             [:parent_ref, :kind], [:kind, :parent_ref, :kind]],
  #    #<Set: {:kind, :parent_ref, :reference}>=>[[:kind, :parent_ref, :reference]],
  #    #<Set: {:parent_ref, :kind, :status}>=>[[:parent_ref, :kind, :status]]} 
g = h.each_key.with_object({}) do |k,g|
  g[k] = h[k].dup
  h.each { |kk,v| g[k].concat(v) if k < kk }
end 
  #=> {#<Set: {:reference}>=>[[:reference], [:kind, :parent_ref, :reference]],
  #    #<Set: {:parent_ref, :kind}>=>[[:parent_ref, :kind], [:parent_ref, :kind],
  #             [:kind, :parent_ref, :kind], [:kind, :parent_ref, :reference],
  #             [:parent_ref, :kind, :status]],
  #    #<Set: {:kind, :parent_ref, :reference}>=>[[:kind, :parent_ref, :reference]],
  #    #<Set: {:parent_ref, :kind, :status}>=>[[:parent_ref, :kind, :status]]} 
a = g.max_by { |k,v| v.size }
  #=> [#<Set: {:parent_ref, :kind}>, [[:parent_ref, :kind], [:parent_ref, :kind],
  #     [:kind, :parent_ref, :kind], [:kind, :parent_ref, :reference],
  #     [:parent_ref, :kind, :status]]] 
[a.last.first, a.last.drop(1)]
  #=> [[:parent_ref, :kind], [[:parent_ref, :kind], [:kind, :parent_ref, :kind],
  #    [:kind, :parent_ref, :reference], [:parent_ref, :kind, :status]]]
而且
arr
的任何其他元素(在
arr
的所有元素转换为集合之后)都没有更多的超集

请注意,如果需要,可以链接
g
a
的计算

参见集合#[#,#, # #, #] h=集合。每个_与_对象(Hash.new{{h,k{h[k]=[]){s,h| set.each{| ss | h[s]{#=>[#], # #=>[#, # #]} k、 v=h.max_乘以{| |,v | v.size} #=> [#, # [#, #]] [k.to_a,v.map(&:to_a)] #=>[:父项参考,种类], #[[:kind,:parent\u ref,:reference],:parent\u ref,:kind,:status]]
不确定我是否理解问题和您的示例。您所说的“使用最大元素数”是什么意思?你能用另一种方式解释它吗?对我来说,在这种情况下,元素似乎是内部数组。因此,他正在寻找涉及数组数量最多的交集。参见本例中的红色交集:我认为你缺少一些交集:假设你有
b=>[2,3,4]
c=>[2,3,4,5]
此解决方案将错过
[2,3,4]=>[:b,:c]
@DavidGeismar:看来你是对的。它找到的交集是最多的子集,而不是最多的元素。
require 'set'

h = arr.each_with_object(Hash.new { |h,k| h[k] = [] }) { |a,h| h[a.to_set] << a }
  #=> {#<Set: {:reference}>=>[[:reference]],
  #    #<Set: {:parent_ref, :kind}>=>[[:parent_ref, :kind],
  #             [:parent_ref, :kind], [:kind, :parent_ref, :kind]],
  #    #<Set: {:kind, :parent_ref, :reference}>=>[[:kind, :parent_ref, :reference]],
  #    #<Set: {:parent_ref, :kind, :status}>=>[[:parent_ref, :kind, :status]]} 
g = h.each_key.with_object({}) do |k,g|
  g[k] = h[k].dup
  h.each { |kk,v| g[k].concat(v) if k < kk }
end 
  #=> {#<Set: {:reference}>=>[[:reference], [:kind, :parent_ref, :reference]],
  #    #<Set: {:parent_ref, :kind}>=>[[:parent_ref, :kind], [:parent_ref, :kind],
  #             [:kind, :parent_ref, :kind], [:kind, :parent_ref, :reference],
  #             [:parent_ref, :kind, :status]],
  #    #<Set: {:kind, :parent_ref, :reference}>=>[[:kind, :parent_ref, :reference]],
  #    #<Set: {:parent_ref, :kind, :status}>=>[[:parent_ref, :kind, :status]]} 
a = g.max_by { |k,v| v.size }
  #=> [#<Set: {:parent_ref, :kind}>, [[:parent_ref, :kind], [:parent_ref, :kind],
  #     [:kind, :parent_ref, :kind], [:kind, :parent_ref, :reference],
  #     [:parent_ref, :kind, :status]]] 
[a.last.first, a.last.drop(1)]
  #=> [[:parent_ref, :kind], [[:parent_ref, :kind], [:kind, :parent_ref, :kind],
  #    [:kind, :parent_ref, :reference], [:parent_ref, :kind, :status]]]
[[:parent_ref, :kind], [:kind, :parent_ref, :kind],
 [:kind, :parent_ref, :reference], [:parent_ref, :kind, :status]]
arr = [
  [:reference],
  [:parent_ref, :kind],
  [:kind, :parent_ref, :reference],
  [:parent_ref, :kind, :status]
]
require 'set'

sets = arr.map(&:to_set)
  #=> [#<Set: {:reference}>, #<Set: {:parent_ref, :kind}>,
  #    #<Set: {:kind, :parent_ref, :reference}>, #<Set: {:parent_ref, :kind, :status}>]
h = sets.each_with_object(Hash.new { |h,k| h[k] = [] }) { |s,h|
       sets.each { |ss| h[s] << ss if s < ss } }
  #=> {#<Set: {:reference}>=>[#<Set: {:kind, :parent_ref, :reference}>],
  #    #<Set: {:parent_ref, :kind}>=>[#<Set: {:kind, :parent_ref, :reference}>,
  #    #<Set: {:parent_ref, :kind, :status}>]}
k, v = h.max_by { |_,v| v.size }
  #=> [#<Set: {:parent_ref, :kind}>,
  #     [#<Set: {:kind, :parent_ref, :reference}>, #<Set: {:parent_ref, :kind, :status}>]]
[k.to_a, v.map(&:to_a)]
  #=> [[:parent_ref, :kind],
  #    [[:kind, :parent_ref, :reference], [:parent_ref, :kind, :status]]]