笔试算法题(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值的重复率;
样例:
unsigned long HashString(char *lpszFileName, unsigned long dwHashType)
{
unsigned char *key = (unsigned char *)lpszFileName;
unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE;
int ch; while(*key != )
{ ch = toupper(*key++); seed1 = cryptTable[(dwHashType << ) + ch] ^ (seed1 + seed2);
seed2 = ch + seed1 + seed2 + (seed2 << ) + ;
}
return seed1;
}
int GetHashTablePos(char *lpszString, MPQHASHTABLE *lpTable, int nTableSize)
{
const int HASH_OFFSET = , HASH_A = , HASH_B = ;
int nHash = HashString(lpszString, HASH_OFFSET);
int nHashA = HashString(lpszString, HASH_A);
int nHashB = HashString(lpszString, HASH_B);
int nHashStart = nHash % nTableSize, nHashPos = nHashStart; while (lpTable[nHashPos].bExists)
{ if (lpTable[nHashPos].nHashA == nHashA && lpTable[nHashPos].nHashB == nHashB)
return nHashPos;
else
nHashPos = (nHashPos + ) % nTableSize; if (nHashPos == nHashStart)
break;
} return -; //Error value
}
补充:
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)的更多相关文章
- [转载]布隆过滤器(Bloom Filter)
[转载]布隆过滤器(Bloom Filter) 这部分学习资料来源:https://www.youtube.com/watch?v=v7AzUcZ4XA4 Filter判断不在,那就是肯定不在:Fil ...
- 布隆过滤器(Bloom Filter)的原理和实现
什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, ...
- 布隆过滤器(Bloom Filter)详解——基于多hash的概率查找思想
转自:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html 布隆过滤器[1](Bloom Filter)是由布隆(Burton ...
- [转载] 布隆过滤器(Bloom Filter)详解
转载自http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html 布隆过滤器[1](Bloom Filter)是由布隆(Burton ...
- 布隆过滤器(Bloom Filter)详解
直观的说,bloom算法类似一个hash set,用来判断某个元素(key)是否在某个集合中.和一般的hash set不同的是,这个算法无需存储key的值,对于每个key,只需要k个比特位,每个存储一 ...
- 浅谈布隆过滤器Bloom Filter
先从一道面试题开始: 给A,B两个文件,各存放50亿条URL,每条URL占用64字节,内存限制是4G,让你找出A,B文件共同的URL. 这个问题的本质在于判断一个元素是否在一个集合中.哈希表以O(1) ...
- 【面试突击】-缓存击穿(布隆过滤器 Bloom Filter)
原文地址:https://blog.csdn.net/fouy_yun/article/details/81075432 前面的文章介绍了缓存的分类和使用的场景.通常情况下,缓存是加速系统响应的一种途 ...
- 布隆过滤器(Bloom Filter)-学习笔记-Java版代码(挖坑ing)
布隆过滤器解决"面试题: 如何建立一个十亿级别的哈希表,限制内存空间" "如何快速查询一个10亿大小的集合中的元素是否存在" 如题 布隆过滤器确实很神奇, 简单 ...
- 布隆过滤器 Bloom Filter 2
date: 2020-04-01 17:00:00 updated: 2020-04-01 17:00:00 Bloom Filter 布隆过滤器 之前的一版笔记 点此跳转 1. 什么是布隆过滤器 本 ...
- 探索C#之布隆过滤器(Bloom filter)
阅读目录: 背景介绍 算法原理 误判率 BF改进 总结 背景介绍 Bloom filter(后面简称BF)是Bloom在1970年提出的二进制向量数据结构.通俗来说就是在大数据集合下高效判断某个成员是 ...
随机推荐
- 字节流与字符流简单操作(OutputStream、InputStream、Writer、Reader)
操作流程 使用File类打开一个文件 通过字节流或者字符流的子类.指定输出的位置. 进行读/写操作 关闭输入/出 字节流与字符流 在java.io包中操作文件内容主要有两大类:字节流字符流.两大类分为 ...
- E20180225-hm-xa
variation n. 变化,变动; 变异,演变; 变奏曲; 变量; auxiliary adj. 辅助的 subscript adj. 下标的,写在下方的,脚注的; n. 下标,脚注,下角数 ...
- php pdo操作数据库
POD扩展是在PHP5中加入,该扩展提供PHP内置类 PDO来对数据库进行访问,不同数据库使用相同的方法名,解决数据库连接不统一的问题. PDO的特点: 性能.PDO 从一开始就吸取了现有数据库扩展成 ...
- bzoj 4568: [Scoi2016]幸运数字【树链剖分+线段树+线性基】
一眼做法,好处是好想好写坏处是常数大,容易被卡(bzoj loj 洛谷开O2 能AC,不开有90分-- 大概就是树剖之后维护线段树,在线段树的每个节点上上维护一个线性基,暴力\( 60^2 \)的合并 ...
- ES的简单增删改查
1.查看全部索引 GET:192.168.100.102:9200/_cat/indices 2.创建名为news的索引 PUT:192.168.100.102:9200/news 3.新增docum ...
- python正则表达式_总结
正则表达式: 作用:正则表达式是用来查找字符串的. 之前:使用正则表达式首先要导入re模块(import re) re.match -- 从字符串的第一个单词开始匹配字符串.如果匹配到则返回一个对象: ...
- Lightoj 1174 - Commandos (bfs)
题目链接: Lightoj 1174 - Commandos 题目描述: 有一军队秉承做就要做到最好的口号,准备去破坏敌人的军营.他们计划要在敌人的每一个军营里都放置一个炸弹.军营里有充足的士兵,每 ...
- HDFS执行getDatanodeReport输出信息
HDFS执行getDatanodeReport输出信息: Name: (192.168.101.100) Hostname: bigsrv Decommission Status : Normal C ...
- C. Two strings 二分 + 预处理
http://codeforces.com/contest/762/problem/C 第一个串str[],第二个sub[] 预处理出prefix[i]表示sub的前i位和str[]的最长lcs去到s ...
- [转]强制取消TFS2008中其它成员的签出文件
本文转自:http://www.cnblogs.com/georgehu/archive/2010/10/23/1859573.html 有个项目,以前的成员离职了,刚好又签出了一个文件在TFS中并且 ...