2013-05-01 11 views
18

Rubyで2つの文字列間の距離を測定できますか?Rubyで2つの文字列間の距離を測定しますか?

すなわち:

compare('Test', 'est') # Returns 1 
compare('Test', 'Tes') # Returns 1 
compare('Test', 'Tast') # Returns 1 
compare('Test', 'Taste') # Returns 2 
compare('Test', 'tazT') # Returns 5 
+0

あなたは違いを意味しますか? – nzifnab

+7

"levenshtein distance ruby​​"を検索し、[Levenshtein-distance](http://en.wikipedia.org/wiki/Levenshtein_distance)を参照してください。 (私は最後の呼び出しが5を返す理由はよく分かりません;最大編集距離は、入力の長さによって[制限されています](http://en.wikipedia.org/wiki/Levenshtein_distance#Upper_and_lower_bounds)) – user2246674

+0

@nzifnabだから、私は整数のリターンが必要です。 –

答えて

18

私はあなたのためにこれを見つけた:素晴らしい出力です

def levenshtein_distance(s, t) 
    m = s.length 
    n = t.length 
    return m if n == 0 
    return n if m == 0 
    d = Array.new(m+1) {Array.new(n+1)} 

    (0..m).each {|i| d[i][0] = i} 
    (0..n).each {|j| d[0][j] = j} 
    (1..n).each do |j| 
    (1..m).each do |i| 
     d[i][j] = if s[i-1] == t[j-1] # adjust index into string 
        d[i-1][j-1]  # no operation required 
       else 
        [ d[i-1][j]+1, # deletion 
        d[i][j-1]+1, # insertion 
        d[i-1][j-1]+1, # substitution 
        ].min 
       end 
    end 
    end 
    d[m][n] 
end 

[ ['fire','water'], ['amazing','horse'], ["bamerindos", "giromba"] ].each do |s,t| 
    puts "levenshtein_distance('#{s}', '#{t}') = #{levenshtein_distance(s, t)}" 
end 

:=)

levenshtein_distance('fire', 'water') = 4 
levenshtein_distance('amazing', 'horse') = 7 
levenshtein_distance('bamerindos', 'giromba') = 9 

出典:http://rosettacode.org/wiki/Levenshtein_distance#Ruby

+1

笑い@ giromba –

11

はるかに単純な、私はいつでもRubyのショーオフよ...

# Levenshtein distance, translated from wikipedia pseudocode by ross 

def lev s, t 
    return t.size if s.empty? 
    return s.size if t.empty? 
    return [ (lev s.chop, t) + 1, 
      (lev s, t.chop) + 1, 
      (lev s.chop, t.chop) + (s[-1, 1] == t[-1, 1] ? 0 : 1) 
     ].min 
end 
+4

これは遅くなるかもしれませんが、文字列以外のもの(例えば、単語のリスト)のためにLevenshteinの距離を計算するコードを適応させたい場合には、とても良い出発点です。 –

+0

実際、それは他のRubyのバージョンより速いと思われます... – DigitalRoss

+0

'require 'levenshtein''答えは、単語の配列、実際には ':hash'と':eql? 'を理解するものの配列に対しても機能します。 –

1

をIアルゴリズムがC言語で実装されているdamerau-levenshtein gemを作成しました

require "damerau-levenshtein" 
dl = DamerauLevenshtein 
dl.distance("Something", "Smoething") #returns 1 
4

あり、実際のパブリックでなければなりませんRubygemsの中のユーティリティメソッドですが、それはとにかく、ありません。

require "rubygems/text" 
ld = Class.new.extend(Gem::Text).method(:levenshtein_distance) 

p ld.call("asd", "sdf") => 2 
関連する問題