2

Dice's Coefficient のスクリプトを作成しようとしていますが、配列の交差に少し問題があります。

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

問題は、&が重複を削除すると、次のようなものが得られることです:

string1="Almirante Almeida Almada"
string2="Almirante Almeida Almada"

puts approx_string_match(string1, string2) => 76.0%

100 を返す必要があります。

uniq メソッドはそれを釘付けにしますが、情報が失われるため、私が作業している特定のデータセットに不要な一致が生じる可能性があります。

すべての重複が含まれている交差点を取得するにはどうすればよいですか?

4

3 に答える 3

4

Yuval F言ったように、使用する必要がありますmultiset。ただし、multisetRuby標準ライブラリにはありませんので、こちらこちらをご覧ください。

アプリケーションにとってパフォーマンスがそれほど重要でない場合でも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"]
于 2009-10-21T12:38:47.193 に答える
1

このリンクから、 Ruby のセットではなくマルチセットを使用して、すべてのバイグラムが出現回数としてカウントされるようにする必要があると思います。この宝石をマルチセットに使用できるかもしれません。これにより、繰り返されるバイグラムに対して正しい動作が得られるはずです。

于 2009-10-21T11:44:44.287 に答える