2011-03-10 9 views
0

単語間の詳細な距離を表示する方法を教えてください。 例えば、プログラムの出力は次のようになります。単語間の詳細な距離

Words are "car" and "cure": 
Replace "a" with "u". 
Add "e". 

レーベンシュタイン距離は、(私が思う)私のニーズを満たしていません。

+1

私はあなたがそれを使用しているように、「距離」のより正確な定義を与える必要があること、そして考えます。 – FrustratedWithFormsDesigner

+0

Levenshtein距離に何が問題なのですか? – sawa

+0

バックグラウンドで何が行われているのかを出力する必要があります。 – SuprDewd

答えて

1

以下を試してください。アルゴリズムはおおよそWikipedia (Levenshtein distance)に従います。以下で使用される言語は、一例としてルビー

使用であり、tsを変更する場合は、次のように

s = 'Sunday' 
t = 'Saturday' 

まず、stは配列になっており、空の文字列が挿入され最初はmは最終的にアルゴリズムで使用される行列になります。各セルはレーベンシュタイン距離だけでなく、という事実のためにウィキペディアにアルゴリズムだけでなく、(非)操作(を開始する場合

ここ
s = ['', *s.split('')] 
t = ['', *t.split('')] 
m = Array.new(s.length){[]} 

mは、しかし、与えられた行列とは異なります、は)何も削除挿入、または置換をやっていない隣接する(左、上、または左上)のセルからそのセルに到達するために使用しました。また、操作のパラメータを記述する文字列を含んでもよい。すなわち、各セルの形式である:

[レーベンシュタイン距離、操作(文字列)]

ここでメインルーチンです。 、今

s.each_with_index{|a, i| t.each_with_index{|b, j| 
    m[i][j] = 
    if i.zero? 
     [j, "started"] 
    elsif j.zero? 
     [i, "started"] 
    elsif a == b 
     [m[i-1][j-1][0], "did nothing"] 
    else 
     del, ins, subs = m[i-1][j][0], m[i][j-1][0], m[i-1][j-1][0] 
     case [del, ins, subs].min 
     when del 
      [del+1, "deleted", "'#{a}' at position #{i-1}"] 
     when ins 
      [ins+1, "inserted", "'#{b}' at position #{j-1}"] 
     when subs 
      [subs+1, "substituted", "'#{a}' at position #{i-1} with '#{b}'"] 
     end 
    end 
}} 

我々はmの右下隅にijを設定し、我々はと呼ばれる配列にセルの内容をアンシフトと逆方向の手順に従います。それは、アルゴリズム以下mのセルを埋めsteps、開始までは

i, j = s.length-1, t.length-1 
steps = [] 
loop do 
    case m[i][j][1] 
    when "started" 
     break 
    when "did nothing", "substituted" 
     steps.unshift(m[i-=1][j-=1]) 
    when "deleted" 
     steps.unshift(m[i-=1][j]) 
    when "inserted" 
     steps.unshift(m[i][j-=1]) 
    end 
end 

次に、操作でない限り、操作と各ステップの文字列を表示します。この特定の例では

steps.each do |d, op, str=''| 
    puts "#{op} #{str}" unless op == "did nothing" or op == "started" 
end 

、それが出力されます:

inserted 'a' at position 1 
inserted 't' at position 2 
substituted 'n' at position 2 with 'r' 
+0

これは私が最初に試したことでしたが、何か間違っていたに違いないでしょう。私はいくつかのbruteforcingをやってしまった。 – SuprDewd

関連する問題