2012-04-28 73 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