我定义两个字符串几乎相等如果:
这两个字符串几乎相同:
HOW DO YOU
HO DO YOU
这些是:
abcdef
bcdef
但这些字符串几乎不相同:
Almost
Anost
也不是这些:
Almost
Aomst
我有这个功能,我试图让它告诉两个字符串是否几乎相等:
def str_almost_equal(a, b)
a.downcase == b.downcase || (a.size == b.size && a.downcase.chars.map.with_index{|c, i| c == b.downcase[i]}.count(false) == 1)
end
使用"aaa"
和"aab"
调用上面的代码评估为true
。
如果除了上面的内容之外,如何扩展我的函数以使字符串几乎相等,字符串长度只相差一个,除了一个字符外,字符相同?
答案 0 :(得分:1)
使用"模糊字符串匹配" Gemfile中的gem:
gem 'fuzzy-string-match'
它非常易于使用:
2.2.7 :001 > require 'fuzzystringmatch'
=> true
2.2.7 :002 > jarow = FuzzyStringMatch::JaroWinkler.create(:pure)
=> #<FuzzyStringMatch::JaroWinklerPure:0x007fa08c4d8710>
2.2.7 :003 > jarow.getDistance('Almost', 'Aomst')
=> 0.8900000000000001
2.2.7 :004 > jarow.getDistance('Almost', 'Anost')
=> 0.8400000000000001
2.2.7 :005 > jarow.getDistance('Almost', 'Almost')
=> 1.0
我将它用于模糊字符串匹配,它很棒。在我的情况下,我将文件名与歌曲标题匹配,我做了一个笛卡尔联接(基本上,每个文件名与每个标题相匹配),然后对每个文件名进行最高点击,至少在它们是什么时候超过一定的门槛。
答案 1 :(得分:1)
尝试找到两个字符串的交集。
检查此链接here,它提供两个字符串之间相同字符的数量。
您可以检查最长字符串的长度,以及它们相交的字符数。
E.g。如果较长的字符串长度为n,那么交集应该是n-1,并且几乎是&#34;等于
答案 2 :(得分:0)
如果订单不是问题,那么您可以只计算字符的设置差异:
def str_almost_equal(a, b)
shortest, longest = [a.chars,b.chars].minmax_by(&:length)
(longest - shortest).length == 1
end
但是,您的上一次测试表明订单确实很重要。所以这更具有这些特征的longest common subsequence问题:
因此,给定lcs
函数,您可以这样做:
def str_almost_equal(a, b)
shortest, longest = [a,b].minmax_by(&:length)
lcs(a,b) == shortest && longest.length - shortest.length == 1
end
您可以在上面的链接中找到lcs
个功能。这是一个:
def lcs(xstr, ystr)
return "" if xstr.empty? || ystr.empty?
x, xs, y, ys = xstr[0..0], xstr[1..-1], ystr[0..0], ystr[1..-1]
if x == y
x + lcs(xs, ys)
else
[lcs(xstr, ys), lcs(xs, ystr)].max_by {|x| x.size}
end
end
您还可以查看diff-lcs
宝石。