笔试算法题(43):布隆过滤器(Bloom Filter)

议题:布隆过滤器(Bloom Filter)

分析:

  • BF由一个很长的二进制向量和一系列随机映射的函数组成,通过多个Hash函数将一个元素映射到一个Bit
    Array中的多个点,查询的时候仅当所有的映射点都为1才能判断元素存在于集合内;BF用于检索一个元素是否在一个集合中,记忆集合求交集;优点是空间
    和时间效率都超过一般查询算法,缺点是有一定的误判概率和删除困难;

  • 如下图,使用三个哈希函数对每个元素进行映射,这样每个元素对应HashTable中的三个位置,如果查找w是否在HashTable中则仍旧利用三个哈
    希函数对其进行映射,当且仅当三个哈希函数映射的位置的标记都为1的时候,才表明w存在于集合中;但是由于HashTable中的每一个位由所有映射元素
    共享,w的三个映射位置可能分别被其他元素标记,所以此方法存在一定误判的概率;


  • 位数组表示所有单元数据是否存在,K个独立Hash函数用于判断某个元素是否已经存在。存入一个数据时将K个独立Hash函数映射的位都置位1,检测新数
    据是否存在位数组中时再次计算K个独立Hash函数,如果所有的映射位都为1,则说明数据重复;只要有一个独立Hash函数的映射结果不为1说明数据没有
    重复;

  • 由于位数组中每一个位可能同时对应多个数据的映射,所以不能删除已经插入的数据(Counting Bloom
    Filter将每个位扩展为可计数的结构,所以可以应对删除操作);

  • 实现难点在于如果根据N个待插入元素,决定位数组大小M,以及K个独立Hash函数。如果在错误率不大于E的情况下,M至少为
    N*lg(1/E)*lge(lg以2为底,e是自然常数,所以lge大约为1.44);当Hash函数个数为ln2*(M/N)的时候,期望错误率最小;

  • 将利用数学计算将大范围内的数值映射到小范围的数组中(字符串可以转换为数字),如果数学计算时间足够快,则可在常数时间定位数据的存放位置;

  • 需要解决数据碰撞(Open Hashing在每个slot上挂载链表用于存储位置重复的元素;Closed
    Hashing利用某种策略将位置重复的元素存储到下一个可用的slot中),所以好的Hash函数非常难找。源自暴雪的Hash函数,一个字符串对应3
    个Hash值,一个用于定位而两外两个用于进一步确定同一位置上的字符串是否相同,如果后面两个Hash值不同于相同位置上的字符串则说明不是同一个字符
    串,则需要reHash或者进行拉链处理;如果都相同则说明是同一个字符串。同时可以扩大Hash表大小以降低Hash值的重复率;

样例:


 1 unsigned long HashString(char *lpszFileName, unsigned long dwHashType)
2 {
3 unsigned char *key = (unsigned char *)lpszFileName;
4 unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE;
5 int ch;
6
7 while(*key != 0)
8 {
9
10 ch = toupper(*key++);
11
12 seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);
13 seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
14 }
15 return seed1;
16 }
17 int GetHashTablePos(char *lpszString, MPQHASHTABLE *lpTable, int nTableSize)
18 {
19 const int HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;
20 int nHash = HashString(lpszString, HASH_OFFSET);
21 int nHashA = HashString(lpszString, HASH_A);
22 int nHashB = HashString(lpszString, HASH_B);
23 int nHashStart = nHash % nTableSize, nHashPos = nHashStart;
24
25 while (lpTable[nHashPos].bExists)
26 {
27
28 if (lpTable[nHashPos].nHashA == nHashA && lpTable[nHashPos].nHashB == nHashB)
29 return nHashPos;
30 else
31 nHashPos = (nHashPos + 1) % nTableSize;
32
33 if (nHashPos == nHashStart)
34 break;
35 }
36
37 return -1; //Error value
38 }

补充:

  • D-Left-Hashing可尽量将数据分散存储到表的各部分,如2-Left-Hashing将表分成两个相等部分,每个部分对应一个Hash函
    数,H1和H2;存储一个新元素的时候,同时计算两个Hash函数得到两个地址H1(key)和H2(key),此时利用某种策略检查哪一个部分的数据负
    载较小,就将新数据存入负载较小的一边,最终分散存储数据;

  • HashTable与Array的区别在于存储元素分布的范围,当存储元素分布范围较为集中的时候,使用确定性的Bit
    Array表明元素是否存在的效率远高于HashTable,1bit就可以独立的确定一个元素是否存在;相反,当存储元素分布范围较广,Bit
    Array存储需要较大的空间,此时使用Hash函数将分布范围较广的元素映射到相对较小的一个范围内,并存储到对应的HashTable中,在没有
    collision的情况下,存储查询时间仍旧为O(1);但问题在于将一个分布较广的集合映射到一个分布较窄的集合中时,肯定会出现不同元素映射到同一
    个元素的误判情况;为了减小误判情况发生的概率,使用k个Hash Function将一个元素对应到HashTable上的k个bits;

参考连接:
http://www.cnblogs.com/allensun/archive/2011/02/16/1956532.html
http://hi.baidu.com/hins_pan/blog/item/329c7bd2d48159113bf3cf79.html

笔试算法题(43):布隆过滤器(Bloom Filter),布布扣,bubuko.com

时间: 2024-10-24 23:58:51

笔试算法题(43):布隆过滤器(Bloom Filter)的相关文章

布隆过滤器(Bloom Filter)详解

布隆过滤器(Bloom Filter)详解 2012-07-13 18:35 by Haippy, 29358 阅读, 6 评论, 收藏, 编辑   布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Fi

基于BitSet的布隆过滤器(Bloom Filter)

布隆过滤器 Bloom Filter 是由Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员.如果检测结果为是,该元素不一定在集合中:但如果检测结果为否,该元素一定不在集合中.因此Bloom filter具有100%的召回率.这样每个检测请求返回有"在集合内(可能错误)"和"不在集合内(绝对不在集合内)"两种情况,可见 Bloom filter 是牺牲了正确率和时间以节省空间. 当

布隆过滤器(Bloom Filter)的原理和实现

什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, gmail等邮箱垃圾邮件过滤功能 这几个例子有一个共同的特点: 如何判断一个元素是否存在一个集合中? 常规思路 数组 链表 树.平衡二叉树.Trie Map (红黑树) 哈希表 虽然上面描述的这几种数据结构配合常见的排序.二分搜索可以快速高效的处理绝大部分判断元素是否存在集合中的需求.但是当集合里

[转载] 布隆过滤器(Bloom Filter)详解

转载自http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html   布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Filter报告某一

探索C#之布隆过滤器(Bloom filter)

阅读目录: 背景介绍 算法原理 误判率 BF改进 总结 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量数据结构.通俗来说就是在大数据集合下高效判断某个成员是否属于这个集合.BF其优点在于: 插入和查询复杂度都是O(n) 空间利用率极高. 例子1: 像Yahoo这类的公共邮件服务提供商,总是需要过滤垃圾邮件. 假设有50亿个邮件地址,需要存储过滤的方法有: 所有邮件地址都存储到数据库. 缺点:每次都需要查询数据库,效率低. 使用Hashtable保存到内

一个用于白名单服务的布隆过滤器(bloom filter)

bloom filter这种数据结构用于判断一个元素是否在集合内,当然,这种功能也可以由HashMap来实现.bloom filter与HashMap的区别在于,HashMap会储存代表这个元素的key自身(如key为"IKnow7",那么HashMap将存储"IKnow7"这12个字节(java),其实还需要包括引用大小,但java中相同string只存一份),而bloom filter在底层只会使用几个bit来代表这个元素.在速度上,bloom filter对比

url去重 --布隆过滤器 bloom filter原理及python实现

https://blog.csdn.net/a1368783069/article/details/52137417 # -*- encoding: utf-8 -*- """This module implements a bloom filter probabilistic data structure and an a Scalable Bloom Filter that grows in size as your add more items to it withou

布隆过滤器(Bloom Filter)

一.概念 1. 布隆过滤器是一个数据结构:bit数组+随机映射函数 2. 作用:高效判断某个元素是否在给定的集合中 3. 缺点:有一定的错误识别率,随着数据量越大,错误识别率越大:并且不容易删除 二.原理 1. 加入元素: a. 使用布隆过滤器中的哈希函数,计算元素的哈希值,可能有多个哈希函数,对应多个哈希值 b. 根据所有哈希值,把bit数组中对应下标的值设置为1:如果设置时发现已经全部为1,表示元素重复 2. 判断元素: a. 计算哈希值 b. 判断是否所有对应的下标都为1,都为1存在布隆过

笔试算法题(09):查找指定和值的两个数 &amp; 构造BST镜像树

出题:输入一个已经升序排序的数组和一个数字:要求在数组中查找两个数,这两个数的和正好等于输入的那个数字,输出任意一对数字就可以,要求时间复杂度是O(n): 分析:对于升序排序的数组{-i-j-k-m--},只有可能是i+m=j+k(j和k可能是同一个数),所以可以从两边往中间收缩而忽视其他交叉相加的情况: 解题: 1 void FindSumFactor(int *array, int length, int sum) { 2 int left=0, right=length-1; 3 whil