2012-04-28 142 views
0

我想清理我的音樂庫,注意我的系統上雙打最多的歌曲。我可以將它們全部列出,然後手動進行分類,但這需要很長時間。我想要列表排序最可能的重複。所以如果一首歌會有10個重複,那就意味着有10首相似的歌名,因此我會首先將注意力集中在那首歌上,以保持最佳版本。索引和比較字符串索引或散列

我可以使用使用萊文斯坦字符串比較技術和寶石

require 'levenshtein' 
Levenshtein.distance("string1", "string2") => 1 

比較兩個songnames但是,讓我們說,我有歌曲X號,我將不得不每首歌曲的x倍的比較,因爲我可以」噸依靠正常的檔案,我會錯過一些重複的話。例如

The Beatles - Hey Jude 
Beatles, The - hey jude 
Beatles_-_Hey_Judy_(remastered) 

應該給甲殼蟲樂隊 - 嘿朱迪(X3)

是否有生產基於文件的索引,然後可以進行排序,並會給降序排列的所有副本的方法嗎?一種可以比較的散列?

我知道其他音樂比較方法,但他們有缺陷,這也可用於比較其他類型的文件。

+0

你可能想看看類似[pHash](https://github.com/toy/pHash)的東西,它比較實際的音頻並給出它們匹配的置信度。 – 2012-04-28 18:44:47

+0

似乎是一個有趣的寶石,但安裝後,當我需要oit時,我得到C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.0.11/lib/ffi/library.rb:121:在'ffi_lib中的塊':無法打開庫'.dll':指定的模塊找不到。 (LoadError) – peter 2012-04-28 19:04:39

+0

那麼你需要[下載並安裝phash庫](http://phash.org/download/),該寶石使用。 – 2012-04-28 19:05:43

回答

3

嘗試使用這個代碼

files是文件名的陣列,max_distance是考慮類似名稱的最大距離。

hash = {} 
files.each do |file| 
    similar = hash.keys.select { |f| Levenshtein.distance(f, file) < max_distance } 
    if similar.any? 
    hash[similar.first] += 1 
    else 
    hash.merge!({file => 0}) 
    end 
end 

後,你會得到hash,其中有文件名作爲鍵和「重複」算值,並根據需要,你可以對它進行排序。

+0

我用幾個名字填充文件數組,然後將max_distance初始化爲0,但結果散列中全部爲0例如{「Beatles - The Word .mp3」=> 0,「The Beatles - The Word.mp3」=> 0 ,「披頭士 - 告訴我爲什麼(重新安裝).mp3」=> 0},你能幫我進一步嗎? – peter 2012-04-28 19:28:16

+1

distance = 0表示字符串相等。正如我寫的,你應該選擇一個文件名被認爲是相似的值。它不應該是很大的數字,但不是0。通過實驗拿起它。有關算法的詳細信息,請參閱http://en.wikipedia.org/wiki/Levenshtein_distance。 – Flexoid 2012-04-28 19:38:28

+0

好的,謝謝,我知道了,需要先做一些替換,並計算比較字符串的長度 – peter 2012-04-30 09:36:00