这是我的问题(我用C编程):
我有一些包含DNA序列的大文本文件(每个文件有6500万行,大小约4~5 GB)。在这些文件中有许多重复(不知道有多少重复,但应该有数百万)并且我想在输出中返回一个只有不同值的文件。每个字符串都有一个相关的质量值,所以如果我有5个相同的字符串和不同的质量值,我将保留最好的字符串并丢弃其他4个字符串。
尽可能减少内存需求并提高速度效率是VITAL。 我的想法是使用哈希函数创建一个JudyHS数组,以便将String DNA序列(长度为76个字符并具有7个可能的字符)转换为整数,以减少内存使用(4或8个字节,而不是许多76个字节)数以百万计的参赛作品应该是一项成就。这样我可以使用整数作为索引并仅存储该索引的最佳质量值。问题是我找不到一个哈希函数,UNIVOCALLY定义了这么长的字符串,并产生一个可以存储在整数甚至长整数内的值!
我对哈希函数的第一个想法就像Java中的默认字符串哈希函数:s [0] * 31 ^(n-1)+ s [1] * 31 ^(n-2)+ ... + s [n-1],但我可以获得最大值8,52 * 10 ^ 59 ..太大了。 如何做同样的事情并将其存储在双倍?计算会变慢吗? 请注意,我想要一种方法来UNIVOCALLY定义一个字符串,避免冲突(或者至少它们应该是非常罕见的,因为我必须在每次碰撞时访问磁盘,操作非常昂贵......)
答案 0 :(得分:3)
您有7 ^ 76个可能的DNA序列,并希望将它们映射到2 ^ 32个哈希而不会发生冲突?不可能。
你需要至少log2(7 ^ 76)= 214位才能做到这一点,大约27个字节。
我可以忍受一些碰撞,我建议坚持使用CRC32或md5而不是再发明一个新的轮子。
答案 1 :(得分:1)
为 N 元素获取无冲突哈希函数的“简单”方法是使用良好的混合函数(例如,加密哈希函数)并截断大小,以便哈希结果存在于大小至少为 N 2 的空间中。在这里,你有6500万行 - 这适合26位( 2 26 接近6500万)所以52位“应该足够”。
您可以尝试使用快速加密哈希函数,即使是“破坏”哈希函数,因为这不是与安全相关的问题。 MD4,MD5,SHA-1 ...然后将结果截断为第一个(或最后一个)64位,将其存储为64位整数类型。有可能你不会在你的6500万行中发生任何碰撞;如果你得到一些,他们将非常罕见。
对于哈希函数的优化C实现,查找sphlib。使用提供的sph_dec64le()
函数将8位序列“解码”为64位无符号整数值。