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