优秀的算法设计(一)--布隆过滤器

参考博客:https://blog.csdn.net/xinzhongtianxia/article/details/81294922

布隆过滤器

百度百科:

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。

如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢(O(n),O(logn))。不过世界上还有一种叫作散列表(又叫哈希表,Hash table)的数据结构。它可以通过一个Hash函数将一个元素映射成一个位阵列(Bit array)中的一个点。这样一来,我们只要看看这个点是不是1就可以知道集合中有没有它了。这就是布隆过滤器的基本思想。

Hash面临的问题就是冲突。假设Hash函数是良好的,如果我们的位阵列长度为m个点,那么如果我们想将冲突率降低到例如 1%, 这个散列表就只能容纳m / 100个元素。显然这就不叫空间效率了(Space-efficient)了。解决方法也简单,就是使用多个Hash,如果它们有一个说元素不在集合中,那肯定就不在。如果它们都说在,虽然也有一定可能性它们在说谎,不过直觉上判断这种事情的概率是比较低的。

应用

网页URL的去重,垃圾邮件的判别,集合重复元素的判别,查询加速(比如基于key-value的存储系统)等。

个人理解

如果有一亿个64位长度的url需要加入到内存,请使用占用空间最少的办法。

建立一个 m个bit 长的(1byte =8 bits)数组 ,准备k个hash函数,每个url 通过h1、h2。。。hk 个hash函数进行运算,得到的数字%m ,并将bits数组中对应位置进行取反(初始为0,取反为1),下次查询时,再进行同样的操作,如果每个函数的hash值最后的值在数组上的状态都是1,那就说明这个url已经加入到内存中了。

m的取值与需要处理的样本数量、预期失误率有关

 

n为样本量、p为失误率(比如万分之一、百万分之一)

哈希函数的个数 k 向上取整:

真实失误率估算:

空间要求非常严重、单样本空间大 使用布隆过滤器

面试提示点:

黑名单问题、要求问题极为苛刻、单样本空间大、允不允许失误率。

下面的应用来源自:https://blog.csdn.net/xinzhongtianxia/article/details/81294922,感谢这位博主的讲解

BloomFilter的应用

    黑名单
    比如邮件黑名单过滤器,判断邮件地址是否在黑名单中
    排序(仅限于BitSet)
    仔细想想,其实BitSet在set(int value)的时候,“顺便”把value也给排序了。
    网络爬虫
    判断某个URL是否已经被爬取过
    K-V系统快速判断某个key是否存在
    典型的例子有Hbase,Hbase的每个Region中都包含一个BloomFilter,用于在查询时快速判断某个key在该region中是否存在,如果不存在,直接返回,节省掉后续的查询。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值