两根弦几乎相等

时间:2017-09-26 00:01:40

标签: ruby string

我定义两个字符串几乎相等如果:

  1. 他们有相同的长度,或
  2. 他们的长度相差一个,字符串相差一个字符。
  3. 这两个字符串几乎相同:

    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

    如果除了上面的内容之外,如何扩展我的函数以使字符串几乎相等,字符串长度只相差一个,除了一个字符外,字符相同?

3 个答案:

答案 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必须等于较小的字符串(换句话说,小字符串必须完全包含在较大的字符串中,但不一定是连续的)
  • 较大的字符串必须大一个字符

因此,给定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宝石。