如何返回具有重复元素的Ruby数组交集? (骰子系数中的双字母问题)
-
05-07-2019 - |
题
我正在尝试编写Dice的系数,但是我对阵列交叉点有点问题。
def bigram(string)
string.downcase!
bgarray=[]
bgstring="%"+string+"#"
bgslength = bgstring.length
0.upto(bgslength-2) do |i|
bgarray << bgstring[i,2]
end
return bgarray
end
def approx_string_match(teststring, refstring)
test_bigram = bigram(teststring) #.uniq
ref_bigram = bigram(refstring) #.uniq
bigram_overlay = test_bigram & ref_bigram
result = (2*bigram_overlay.length.to_f)/(test_bigram.length.to_f+ref_bigram.length.to_f)*100
return result
end
问题是,和&amp;删除重复项,我得到这样的东西:
string1="Almirante Almeida Almada"
string2="Almirante Almeida Almada"
puts approx_string_match(string1, string2) => 76.0%
它应该返回100.
uniq方法指出它,但是信息丢失,可能会在我工作的特定数据集中带来不必要的匹配。
如何获得包含所有重复项的交叉点?
解决方案
正如 Yuval F
所说,你应该使用 multiset
。但是,Ruby标准库中没有 multiset
,请查看此处和此处。
如果性能对您的应用程序并不重要,您仍然可以使用 Array
并使用一点代码来完成。
def intersect a , b
a.inject([]) do |intersect, s|
index = b.index(s)
unless index.nil?
intersect << s
b.delete_at(index)
end
intersect
end
end
a= ["al","al","lc" ,"lc","ld"]
b = ["al","al" ,"lc" ,"ef"]
puts intersect(a ,b).inspect #["al", "al", "lc"]
其他提示
根据@pierr的回答,我玩弄了一段时间,结果就是这样。
a = ["al","al","lc","lc","lc","lc","ld"]
b = ["al","al","al","al","al","lc","ef"]
result=[]
h1,h2=Hash.new(0),Hash.new(0)
a.each{|x| h1[x]+=1}
b.each{|x| h2[x]+=1}
h1.each_pair{|key,val| result<<[key]*[val,h2[key]].min if h2[key]!=0}
result.flatten
<代码> =&GT; [&quot; al“,”al“,”lc“]
这可能是 a
&amp;的多重交叉。 b
但是不要接受我的话,因为我没有对它进行足够的测试以确定。
不隶属于 StackOverflow