算法与数据结构 - 布隆过滤器

首先说布隆过滤器的干嘛的
  • 能够快速判断一个元素是否在一个集合中
题目描述
  • 一个网站有 100 亿 url 存在一个黑名单中,每条 url 平均 64 字节。这个黑名单要怎么存?若此时随便输入一个 url,你如何快速判断该 url 是否在这个黑名单中?假如允许万分之一的概率出错(这个出错代表宁可错杀三千不可漏掉一个)
思路
  • 1.用一个HashSet 但是我们计算一下需要的内存大小:100亿 * 64 / 1024 / 1024 / 1024 = 640GB(不算乱七八糟的变量什么的)
  • 2.用布隆过滤器,思路就是把所有的URL经过K个哈希算法得到K个哈希码值,然后用K个哈希码值去 % bit数组的大小(m 单位bit),然后把这些位置置为1(描黑),这个叫做进入了布隆过滤器,然后把所有的url都经过这样的处理。之后把想要判断的url放进布隆过滤器中,看是否全部描黑了(都匹配上了)那么这个就是黑名单里的,有一个不满足那就不是。我们用一个bit数组来存储,需要我们自己用int类型的数组实现一个位数组:
/**
 * 这里是想做一个布隆过滤器
 * 首先自己要实现一个比特数组
 * @author zhx
 */
public class BitArray {

    public static void main(String[] args) {
   		// 一个int表示四个字节,一个字节表示8个bit位 1000个int 表示32000bit位
        int[] arr = new int[1000]; 
        //布隆过滤器 想把第30000的位置描黑
        int index = 30000;
        //把数组平分成1000个也就是0~999, 首先判断落在哪个0~999的哪个位置,我称为桶
        int intIndex = index / 32;
        System.out.println(intIndex);
        //描述的是把这个桶下的哪个bit位描黑
        int bitIndex = index % 32;
        System.out.println(bitIndex);
        //1 << bitIndex 表示把第bitIndex位置的数从0变成1 ,然后与之前的数做一个或的运算
        arr[intIndex] = (arr[intIndex] | (1 << bitIndex));
    }
}
  • 下面的是我画的帮助理解的图
    在这里插入图片描述
  • 你会问我那么这里的 申请的bit数组大小m怎么确认?哈希函数个数怎么确认?
    • (1)计算数组大小: m = − n ∗ ln ⁡ p ( ln ⁡ 2 ) 2 m = - \frac {n * \ln p}{(\ln 2)^2} m=(ln2)2nlnp 其中n为样本量即100亿, p为误差概率即0.0001 最后: m = − 10000000000 ∗ ln ⁡ 0.0001 ( ln ⁡ 2 ) 2 = 22.3 G B m = - \frac {10000000000 * \ln 0.0001}{(\ln 2)^2} = 22.3GB m=(ln2)210000000000ln0.0001=22.3GB 这就是我们需要的内存大小,比640GB小的多的多了
    • (2)计算哈希函数个数: K = ln ⁡ 2 ∗ m n K = \ln 2 * \frac {m}{n} K=ln2nm m,n都是上面所求的,直接向上取整,直接带入
      K = ln ⁡ 2 ∗ 23 ∗ 1024 ∗ 1024 ∗ 1024 ∗ 8 10000000000 = 13 K = \ln 2 * \frac {23 * 1024 * 1024 * 1024 * 8}{10000000000} = 13 K=ln210000000000231024102410248=13
      现在需要的哈希函数个数就是13个,然后由于m向上取整了,需要我们进行重新计算误差率p
      p = ( 1 − e − n ∗ K m ) K p = (1 - e ^ {- \frac {n * K}{m}}) ^K p=(1emnK)K 最后的结果是十万分之6左右。。比之前还低
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值