2011-10-18 22 views
0

我有一個數據庫中的學院(學校模型)列表,我有用戶輸入,應該決定哪個學校鏈接用戶。考慮到可能的拼寫錯誤,我可以使用什麼gem /算法來查找字符串?

問題是,人類是錯誤的。因此,而不是邁阿密大學,他們可以輸入邁阿密大學或波士頓大學而不是波士頓學院。

我需要能夠找到這些學校,儘管有這些錯誤,並且至少要爲用戶提供類似學校名稱的列表(如果不存在明確的匹配)。我不想使用像獅身人面像或任何全文獨立搜索引擎,因爲這種搜索只發生在註冊和字符串很小。

有關解決方案的任何想法?

在此先感謝你們。

+0

一個可能的解決方案是利用jQuery的自動完成。 – bricker

+2

@hmind:你的標題說你的算法後面...一個容易的寫法是:對於每個學校,你計算它的*「Levenhstein編輯距離」*與用戶輸入的內容。如果你的學校數據庫是正確的,那麼編輯距離最短的將是最有可能的匹配。 http://en.wikipedia.org/wiki/Levenshtein_distance在做這樣的事情時,你可以得到*非常喜歡的東西,但是簡單地計算所有的編輯距離並在最低的那個中進行選擇應該會給出好的結果。算法本身只有幾行代碼(並且有一個很好的「動態編程」版本) – TacticalCoder

回答

1

你可以看看text gem,雖然我不認爲它會幫助像「波士頓學院」/「波士頓學院」這樣的東西。這些類型的錯誤範圍相當大;我不確定處理這個問題的最佳方法是什麼。

0

我使用的是基於回答here的strikematch,雖然它可能更適合可變長度的字符串。

#Returns between 0 and 1 based on how close two strings are 
def strikematch(str1, str2) 
    str1.downcase! 
    pairs1 = (0..str1.length-2).collect {|i| str1[i,2]}.reject { 
    |pair| pair.include? " "} 
    str2.downcase! 
    pairs2 = (0..str2.length-2).collect {|i| str2[i,2]}.reject { 
    |pair| pair.include? " "} 
    union = pairs1.size + pairs2.size 
    intersection = 0 
    pairs1.each do |p1| 
    0.upto(pairs2.size-1) do |i| 
     if p1 == pairs2[i] 
     intersection += 1 
     pairs2.slice!(i) 
     break 
     end 
    end 
    end 
    (2.0 * intersection)/union 
end 
3

我使用由MySQL實現的Soundex哈希函數。 Docs。向用戶提供可能匹配的下拉菜單和「創建新的」操作時可以很好地工作。

+0

不錯,從來不知道mysql已經建立了soundex。看來postgres還支持soundex和差異函數以及其他一些文本算法。 http://www.postgresql.org/docs/8.3/static/fuzzystrmatch.html – trogdor33

相關問題