![7b5ea93aac94f69c29500244d60ff1e9.png](https://i-blog.csdnimg.cn/blog_migrate/739f1115bec2cfe7f976622cb2727ed6.jpeg)
使用场景
判断一个元素是否在一个集合中。
- 单词处理软件中,需要检查一个英语单词是否拼写正确(判断拼写的单词是否在单词库中)。
- 网页黑名单系统。
- 垃圾邮件过滤系统。
- 爬虫的网址判重系统。
- 解决缓存穿透问题。
原理
利用内存中的一个长度是m的位数组B,对其中所有的位置都置0。
![b9a11625edcf9346ae4209cd93db9b2b.png](https://i-blog.csdnimg.cn/blog_migrate/cde2a824c0e7909bf67af71cd374196b.jpeg)
然后对每个遍历过的对象根据k个不同的散列函数执行散列,每次散列的结果都是不大于m的一个整数a。根据散列得到的数在位数组B对应的位上置1,也就是让B[a] = 1。
![71e70f6febaebc8ca8b4b0ee21116d5d.png](https://i-blog.csdnimg.cn/blog_migrate/bc49a0ee2e2b91e1e25ca61c2cb3df9e.jpeg)
![03d390639722f40fae17c73501b10d9c.png](https://i-blog.csdnimg.cn/blog_migrate/6b67698c0671728eb318d7252ebe4f2e.png)
每次插入一个对象,执行k次散列,只有当全部位都置1了才认为这个对象已经遍历过。
需要注意的是,布隆过滤器如果返回不包含某个对象,那肯定是没在集合中增加过这个对象;如果返回包含某个项目,但其实可能没有增加过这个人对象,所以有误判的可能。
存储的对象和位数比率估计布隆过滤器的误判率如图:
![e9e140e221553bdc5fc904f144a18441.png](https://i-blog.csdnimg.cn/blog_migrate/71dce8a52bb3f14ea42fd37000519c43.jpeg)
为每个对象分配两个字节就可以达到千分之几的冲突。例如一个比较保守的实现,在爬虫网址判重模块,为每个URL分配4个字节,项目和位数之比是1:32,误判率是0.00000021167340,对于5000万量级的URL,布隆过滤器只占用200M的空间,并且重排速度极快,一遍下来不到两分钟。
代码实现
![afbd19c7cce31695e324afc19b810485.png](https://i-blog.csdnimg.cn/blog_migrate/4dbe86f23d1ae39ec7bae8c69eac8626.jpeg)
![c72d355881260ed76ed97db9b3e3ce69.png](https://i-blog.csdnimg.cn/blog_migrate/e45afa152cedd146b31cc6ff743fc0ea.jpeg)
![a5109e3c16980ba9b81a1d654c48e91c.png](https://i-blog.csdnimg.cn/blog_migrate/9f5542e68c783b36944ba1f2dc40037c.png)
优缺点
- 优点:空间占用小,速度快。
- 缺点:存在一定的误判率,不支持删除。