笔试算法题(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年提出的二进制向量数据结构.通俗来说就是在大数据集合下高效判断某个成员是 ...
随机推荐
- Bootstrap指定表格字段宽度
默认情况下,表格会占据屏幕所有宽度,可以使用bootstrap的布局功能.但表格标题字段的宽度必须与相应字段内容的宽度一致. <div class="container"&g ...
- QT笔记1
1 第一个就是helloworld窗体啦 #include <qapplication.h> #include <qpushbutton.h> int main( int ar ...
- bzoj 4826: [Hnoi2017]影魔【单调栈+树状数组+扫描线】
参考:https://www.cnblogs.com/lcf-2000/p/6789680.html 这是一个相对码量少的做法,用到了区间修改区间查询的树状数组,详见:www.cnblogs.com/ ...
- Java-String 类的常用方法
Java 中 String 类的常用方法 Ⅰ String 类提供了许多用来处理字符串的方法,例如,获取字符串长度.对字符串进行截取.将字符串转换为大写或小写.字符串分割等,下面我们就来领略它的强大之 ...
- 通过IDEA制作包含Java应程序的Docker镜像
IDEA官网在IDEA中把Java App制作成Docker镜像并启动一个容器运行 在idea上使用docker作为java的开发环境[][] ubuntu+docker+docker-compose ...
- IDEA远程调试Tomcat程序
如何使用 Idea 远程调试 Java 代码 IDEA远程调试的 基本就是在服务端先设置Tomcat服务器启动脚本catalina.bat,然后在客户端IDEA上进行参数配置,最后二者可以通过Sock ...
- _bzoj1016 [JSOI2008]最小生成树计数【生成树】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1016 其实原题不叫这个的,而且原题是有一个背景故事的... 首先,容易得知,一个最小生成树不 ...
- RHEL5.6配置本地yum源
试验环境:RedHat Enterprise Linux 5.6(虚拟机) 一.挂载镜像 配置yum源第一步需要挂载镜像,或者直接复制操作系统的光盘文件至操作系统目录中. 挂载镜像命令如下: moun ...
- Android Dialogs(4)Dialog事件处理
Passing Events Back to the Dialog's Host When the user touches one of the dialog's action buttons or ...
- 456 132 Pattern 132模式
给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj.设计一个算法,当 ...