我有一个二维数组:
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]
放在一边。
您将如何处理/创建这样的算法。
答案 0 :(得分:0)
暴力,使用排列:
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]]
答案 1 :(得分:0)
假设二维数组是一个字符串数组,其中每个字符串都是一个字符数组。 假设我们有以下字符串:
CDB
BC
CBA
FDE
EDBC
首先按升序对每个字符串进行排序。
BCD
BC
ABC
DEF
BCDE
然后对字符串进行排序。
ABC
BC
BCD
BCDE
DEF
对于每个元素,找到出现在最长的连续字符串序列中的元素。在我们的示例中,它将是B和C。它们的连续字符串是具有非空交集的最大字符串。
答案 2 :(得分:0)
我相信您的问题与this one相关,而此answer是相关的。
您可以将输入内容翻译为简称以提高可读性:
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]}
因此:a
存在于集合1和3中,b
存在于集合2、3和4中...
然后您可以将这些集合分组在一起:
grouped_sets = Hash.new{|h, k| h[k] = []}
grouped_values.each do |value, sets|
grouped_sets[sets] << value if sets.size > 1
end
p grouped_sets
# => {[1, 3]=>[:a], [2, 3, 4]=>[:b, :c]}
因此,集合1和3的交集为[:a]
,集合2、3和4的交集为[:b, :c]
。
最后,您可以选择具有最多集合或具有最多元素的交点。
答案 3 :(得分:0)
arr = [
[:reference],
[:parent_ref, :kind],
[:kind, :parent_ref, :reference],
[:parent_ref, :kind],
[:parent_ref, :kind, :status],
[:kind, :parent_ref, :kind]
]
请注意,我已修改示例中给出的keys
,使其包括两种重复类型。
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]
转换为集合后,是array
的以下其他元素的子集:转换为集合后:
[[:parent_ref, :kind], [:kind, :parent_ref, :kind],
[:kind, :parent_ref, :reference], [:parent_ref, :kind, :status]]
并且arr
的其他任何元素(在arr
的所有元素都转换为集合之后)没有更多的超集。
请注意,如果需要,可以将g
和a
的计算链接起来。
请参见Set#<。
如果arr
或arr
的任何元素都不能包含重复项,则当然可以简化计算。
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]]]