我有一个1,000,000个字符串的排序列表,最大长度为256个,带有蛋白质名称。每个字符串都有一个关联的ID。 我有另一个未分类的4,000,000,000个字符串列表,最大长度为256,文章中的单词和每个单词都有一个ID。
我想找到蛋白质名称列表和文章单词列表之间的所有匹配项。 我应该使用哪种算法?我应该使用一些prebuild API吗?
如果算法在没有特殊硬件的普通PC上运行会很好。
算法所需的时间估计会很好,但不是强制性的。
答案 0 :(得分:1)
40亿个字符串是很多要搜索的字符串。
您可以将整个数据结构放入内存哈希中以便快速查找,但更有可能您希望将整个列表存储在更宽敞(但速度更慢)的磁盘上,在这种情况下,排序列表会自行调整相对有效的二进制搜索算法。
如果您的二进制搜索或此类函数被称为find_string_in_articles()
,则伪代码:
foreach $protein_name ( @protein_names ) {
if ( $article_id = find_string_in_articles( $protein_name ) ) {
print( "$protein_name matches $article_id\n" );
}
}
答案 1 :(得分:1)
您可以对它们进行排序,然后执行“mergesort”,它实际上不会合并但会发现重复/重叠。维基百科对此有很好的参考。
对该数据量进行排序可能需要比您可访问的内存更多的内存。我不知道unix排序(在Windows / Mac上也可以)可以处理,但任何体面的SQL数据库都可以做到。
另一种可能性是在蛋白质名称上使用基数树(以A开头的那些转到bin A,B转到bin B等)。然后只需循环遍历4亿个单词并找到重叠(您可能必须实施多个深度基数合并以一次丢弃更多蛋白质)。
答案 2 :(得分:1)
这实际上是一种关系连接。假设您尚未对文章单词进行排序,则基本算法应为:
for word in article_words:
if (proteins.find(word)):
found_match(word)
proteins.find()是困难的部分,你必须尝试获得最佳性能,这类问题是缓存效果开始发挥作用的地方。我首先尝试使用基数排序,它非常简单并且可能足够快,但二进制搜索和散列也是替代方案。
答案 3 :(得分:0)
听起来像你应该使用二叉树的东西。
答案 4 :(得分:0)
我会以两种方式之一来解决这个问题。