按位运算以查找数组中是否存在数字

时间:2015-10-17 00:52:29

标签: arrays bit-manipulation bitwise-operators

此问题已被多次询问,但建议的答案并非我正在寻找的内容。

  

问题:有没有办法弄清楚数组是否包含给定的数组   数?

     

假设:数组中的元素保证为   独特。该数组没有范围内的所有元素。排列   是无序的。编写数组的程序就是这样的程序   执行检查。所以在编写数组之前,它可以做一些   预处理将保存在内存中。

我试图提出一种方法,它不需要将元素保存在内存中,也不会以小块的形式从磁盘加载元素。是否存在类似于"按位XOR方法的方法,以在唯一数字上找到数组中的1个重复元素"。原因是:我有组中的数字并存储在磁盘上,我只想加载具有手头号码的组。我正在寻找一些东西,比如组中所有元素的XOR,然后根据手头的数字和XOR值确定组是否有数字。

1 个答案:

答案 0 :(得分:2)

您可以使用bloom filter概率地执行此操作,该{{3}}基于哈希表。

散列表的工作原理是将元素存储在数组中,并由元素的散列索引。存储数字时,您可以使用数字x%10。然后,您的哈希表可能有10个插槽,可以在其中放入10个数字。

在这种情况下,您只想知道某个号码是否存在,因此每个插槽可能只需要一个插槽。使用这个简单的示例,如果一个组包含数字{5,17,18,76},则具有10位的散列表将具有设置为索引5,6,7,8的位,并且其他位将是0.然后,当您想知道该组的编号是否为91时,您会知道该组没有此编号。但是,如果您想知道该组是否具有数字35,您会发现该位已设置。在这种情况下,您只知道组可能有此号码。当两个不同的元素碰巧具有相同的散列时,这种不确定性是由散列冲突引起的。您可以通过使哈希表更大来减少此不确定性,以便存在更多潜在的哈希值,并减少冲突的可能性。但是,即使您的哈希表非常大,这仍然具有非常重要的错误可能性,例如。 1000-10,000个插槽。

布隆过滤器有助于进一步降低这种不确定性,同时最小化所需的内存(插槽)。在简单哈希表中,对于您插入的每个元素,您只在哈希表中设置1位,使用布隆过滤器,您可以在哈希表中设置多个位。为此,您有多个哈希函数,例如。 f(x), g(x), h(x), ...,告诉你要设置哪些位。

在具有三个哈希函数和20个广告位的示例中,您可能拥有f(x)=x%20g(x)=floor(x/20)%20h(x)=((x%7)+f(x))%20。假设您要在哈希表中插入3个数字--35,171,82,那么您可以设置以下位:

  • 对于35,设置位15,1,0
  • 对于171,设置位11,8,14
  • 对于82,设置位2,4,7

现在,假设您要检查数字80是否存在。相关位是:0,4,3。您注意到虽然位0和4已设置,但位3不是,因此,您知道80不在组中。

如果您最佳地选择散列函数的数量,则在布隆过滤器中每个元素少于10位,<1%误报率。每个元素3-5位,您仍然可以获得<~50%的误报率。由于我们计算位数,您可以轻松地使用1024位布隆过滤器(使用相当于32个4字节整数的内存),并存储100-200个元素,同时仍然具有非常低的误报率。