是否有一种有效的字符串列表模糊重复数据删除算法?

时间:2013-04-06 13:33:32

标签: algorithm duplicates duplicate-removal

例如,我有一长串字符串,每个字符串大约有30-50个字符,我想删除与该列表中某些其他字符串类似的字符串(只留下一个重复项系列中的一个字符串)

我研究了各种字符串相似度算法,例如Levenstein距离和this article中提出的方法。它们确实有效,但速度很慢 - 我提出的最佳算法表现出O(n ^ 2)复杂度,需要大约1.5秒来处理3000个字符串的列表。

是否有一些快速重复删除这些列表的方法?

2 个答案:

答案 0 :(得分:2)

匹配DNA字符串(或重新组装片段)时经常会出现此问题。第一种方法是将字符串拆分为kmer s,子串,其中 4个相邻字母。所以

abcdefgh

会变成:

abcd + bcde + cdef + defg + efgh

对于完整的字典,这些子字符串可以被输入到哈希表中,每个哈希表都作为有效负载包含它们的原始字符串(它们的数字)的列表(并且可能找到它们的偏移量)

要搜索,将字符串下的字符串视为字典,并在哈希表中查看其片段。现在 hit 将导致找到所有五个片段,并具有正确的偏移量。部分命中将产生少于五个碎片,但具有正确的偏移。

当然,搜索会产生很多假阴性命中,但是通过组合倒排索引列表的(逻辑AND),并且只选择关于<的匹配< / em>正确的索引,事情变得非常快。

对于OP问题中的问题大小,运行时间可能是几(几十)毫秒。

BTW:作为这种方法的副作用,取代将与indels几乎相同。在这个例子中,他们会将一个(在结尾处)破坏为四个(在中间)kmer-matches。对于较大的字符串,这对于小字符串来说不是问题(就像在示例中那样(并且您可以使用较小的片段)

更新:我刚刚阅读了该链接,看起来他们也使用了2-mers(并在其上提供了一些统计信息)

答案 1 :(得分:1)

如果您的相似度很强(例如Levenshtein距离1),那么您可以按顺序处理字符串列表,为当前字符串生成所有可能的“关闭”字符串,并在哈希表中查找该关闭字符串。如果它在那里,跳过原始字符串。如果没有,输出它并将其添加到哈希表。

此算法依赖于能够生成字符串的所有关闭字符串,并且不会有太多字符串。 (这就是我所说的“强”的意思。)

作为一种可能的优化,您可以在哈希表中存储多个原始字符串。例如,如果你想要Levenshtein距离3,你可以在哈希表中存储距输出字符串1的所有字符串,然后在检查新字符串时查找距离为2的字符串。