我需要将查询位序列与高达一百万位序列的数据库进行比较。所有位序列都是100位长。我需要尽可能快地查找。是否有任何包可以快速确定两个比特序列之间的相似性? --Edit--位序列是位置敏感的。
我见过possible algorithm on Bit Twiddling Hacks但是如果有一个现成的包会更好。
答案 0 :(得分:2)
如果数据库是静态的,您可能希望在其上构建树数据结构。
以递归方式或多个线程搜索树,每次搜索保留实际的差异变量。如果实际差异大于您认为的“相似”,则中止搜索。
E.g。假设我们有以下树:
root
0 1
0 1 0 1
0 1 0 1 0 1 0 1
如果你想寻找类似于011的模式,并且只希望最多允许1个不同的位,那就像这样搜索(递归或多线程):
这一直持续到你找到了你的位模式。
如果您的位模式更具动态性并在应用程序中进行更新,则必须更新树。
如果内存有问题,请考虑转到64位。
答案 1 :(得分:2)
如果你想查找50个大多数匹配模式,我们可以假设输入数据集是静态的(或者可以动态更新),你可以重复上一个注释的初始阶段,这样:
然后,使用以下算法:
对距离2,距离3,......重复此操作,直到你有足够的模式。
如果所需图案的数量不是太大,而且平均距离也不是太大,那么图案之间的实际比较数可能只有几个百分点。
不幸的是,由于模式将使用高斯曲线分布,因此仍需要检查相当多的模式。我没有对它进行数学检查,但在实践中,如果你不想要数百万的太多模式,并且平均距离不是太远,你应该能够找到最接近的一组通过只检查总位模式的几个百分点来确定模式。
请让我及时了解您的结果。
答案 2 :(得分:1)
我提出了第二种选择。
对于百万个的每个位模式计数位数并将位模式存储在STL multi_map中(如果您使用C ++编写)。
然后计算模式中的位数。假设您在位模式中设置了N位。
如果您现在想要允许最多D差异,请查找具有ND,N-D + 1,...,N-1,N,N + 1,... N的multi_map中的所有位模式+ D-1,N + D位。
不幸的是,multi_map中位模式的划分将遵循高斯模式,这意味着在实践中你仍然需要比较一些位模式。
(最初我认为这可以通过计算偶数0和不均匀的1来解决,但事实并非如此。)
假设您想要允许1个差异,您必须在100个可能的插槽中查找multi_map中的3个插槽,留下3%的实际位模式进行完全比较。