海量元素中是否存在某一元素快速且高置信度判断方案

布隆过滤器,Bloom Filter
1970年由伯顿·霍华德·布隆(Burton Howard Bloom)提出

数据结构组成

  • 一个很长的二进制向量
  • 若干哈希函数

布隆过滤器有两种操作
添加元素

  • 将该元素由n个哈希函数分别进行运算获得n个哈希值
  • 将n个哈希值对应的二进制向量中的n为置为1
    总结:布隆过滤器添加元素其实是将元素转换为了n个比特位,不存储元素本身

判断元素是否存在

  • 将该元素由n个哈希函数分别进行运算获得n个哈希值
  • 判断n个哈希值对应的二进制向量中的n为是否全为一
    总结:添加元素的时候将元素转成了n个比特位,判断存不存在就看这几个比特位存不存在

布隆过滤器以误判率为代价节省了空间和时间消耗

误判率原因:
布隆过滤器原理,每一个哈希函数相当于提取元素的部分信息,n份部分信息已存在则说明该元素已存在
一个例子,有两个人,金发单眼皮张三、黑发双眼皮李四,邀请名单记录了金发、黑发、单眼皮、双眼皮四个特征,假如有个白发单眼皮王五,显然不在名单中,但是有个金发双眼皮老六,就造成了误判。
布隆过滤器判定存在但实际不一定存在,布隆过滤器判定不存在则一定不存在。

使用场景

布隆过滤器使用场景判断给定数据是否存在:比如判断一个数字是否存在于包含大量数字的数字集中(数字集很大,上亿)、 防止缓存穿透(判断请求的数据是否有效避免直接绕过缓存请求数据库)等等、邮箱的垃圾邮件过滤(判断一个邮件地址是否在垃圾邮件列表中)、黑名单功能(判断一个 IP 地址或手机号码是否在黑名单中)等等。去重:比如爬给定网址的时候对已经爬取过的 URL 去重、对巨量的 QQ 号/订单号去重。去重场景也需要用到判断给定数据是否存在,因此布隆过滤器主要是为了解决海量数据的存在性问题。

布谷鸟过滤器,cuckoo filter
一维数组结构,数组中每个元素为固定的四个字节数组,数组中每个元素称为一个桶,每个桶中的字节称为指纹,每个桶可以存储四个指纹

插入操作
计算指纹,x为原始数据,布谷鸟过滤器不存储原始数据而是存储原始数据的指纹

fp = fingerprint(x) //计算指纹

使用哈希函数计算出备选的两个桶

p1 = hash(x)  //位置1   	HASH1
p2 = p1 ^ hash(fp) //位置2  HASH2  不需要原始数据就可以计算,挤兑的时候直接使用指纹和原来的位置计算挤兑后的位置

初始化一个给定容量的过滤器Filter,这个容量数为2的n次方,如果不为2的n次方,内部会通将其转化为2的n次方。

先进行一次hash,得出应当插入位置和应当插入的。

如果这个位置(bucket内的4个位置均被占用)插入失败,会进行第二次hash,查看第二个位置能否插入。若第二个位置插入失败,则会随机在两个位置挑选一个将其中的一个值标记为旧值,用新值覆盖旧值,旧值会在重复上面的步骤进行插入。

会对插入的值进行校验,只有当未插入过该值时才会插入成功,若过滤器中已经存在该值,会插入失败返回false。

扩容:如果数组过小,会发生循环挤兑的情况,就可以设置最大挤兑次数,如果超过该次数,进行扩容,重新计算每个指纹的位置。

查找:通过计算哈希值得到两个元素,对两个元素中的8个位置进行指纹对比(上图对比数据),如果对比成功则表示数据存在 只要其中一个相同就成功。如果哈希值和指纹相同时会发生误判(小概率,一个指纹1byte 8 bit表示 256 个方式 )。

删除:因为每个对象的指纹会存储到一个位置中,所以可以通过删除这个指纹来删除数据。删除功能无法使用的情况:如果相同对象存储超过8个,就无法使用删除功能;如果俩数据的哈希值和指纹相同时,会出现误删除情况。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值