实现布隆过滤器 · Standard Bloom Filter以及CountingBloomFilter

想要理解Bloom Filter,其实最好想理解BitMap,这里有一个非常好的帖子理解bitmap,这个帖子浏览了一下好像没看到如何把对应位置置为1,我给大家示范一下,仅供参考


        //比如我要存储10000个URl做黑名单  那么只需要开10000/64 (long 64个bit位) 的long数组
        long[] longs = new long[1 + 10000 / 64]; //大家思考一下为啥加1
        //对www.baidu.com取hash值再模100000为 34,那么应该放入哪个下标的数组呢
        //应该是 longs[0]  因为 34/64=0
        //那应该放在long[0]的哪个位置呢  答案是 34%64
        //那么问题来了 如何将long[0]的第34为变为1呢
        //很简单  1<<34位,然后和long[0]或 如下图 举一个8位的例子
        //   long[0]=0      0 0 0 0 0 0 0 0
        //      1           0 0 0 0 0 0 0 1  1左移2位-》 0 0 0 0 0 1 0 0
        //然后    做或运算   long[0]=0      0 0 0 0 0 0 0 0 
        //                                0 0 0 0 0 1 0 0
        // 结果                            0 0 0 0 0 1 0 0 这样 对应位置就变为le  我猜测这就是java bitset的原理

然乎java里BitSet实现了BitMap这个结构
这里借助bitset实现了一个标准的布隆过滤器

/**
**/
public class BloomFilter {
//hash函数
    class HashFunction {
        public int cap, seed;

        public HashFunction(int cap, int seed) {
            this.cap = cap;
            this.seed = seed;
        }

        public int hash(String value) {
            int ret = 0;
            int n = value.length();
            for (int i = 0; i < n; ++i) {
                ret += seed * ret + value.charAt(i);
                ret %= cap;
            }
            return ret;
        }
    }

    public class StandardBloomFilter {

        public BitSet bits;
        public int k;//k个hash函数  原理可以百度一下
        public List<HashFunction> hashFunc;

        public StandardBloomFilter(int k) {
            this.k = k;
            hashFunc = new ArrayList<HashFunction>();
            for (int i = 0; i < k; ++i)
                hashFunc.add(new HashFunction(100000 + i, 2 * i + 3));//10000只是当初为了过oj,seed最好为质数
            bits = new BitSet(100000 + k);
        }

        public void add(String word) {
            for (int i = 0; i < k; ++i) {
                int position = hashFunc.get(i).hash(word);
                bits.set(position);
            }
        }

        public boolean contains(String word) {
            for (int i = 0; i < k; ++i) {
                int position = hashFunc.get(i).hash(word);
                if (!bits.get(position))
                    return false;
            }
            return true;
        }
    }

计数型布隆过滤器

class HashFunction {
    public int cap, seed;

    public HashFunction(int cap, int seed) {
        this.cap = cap;
        this.seed = seed;
    }

    public int hash(String value) {
        int ret = 0;
        int n = value.length();
        for (int i = 0; i < n; ++i) {
            ret += seed * ret + value.charAt(i);
            ret %= cap;
        }
        return ret;
    }
}

public class CountingBloomFilter {

    public int[] bits;
    public int k;
    public List<HashFunction> hashFunc;

    public CountingBloomFilter(int k) {
        // initialize your data structure here
        this.k = k;
        hashFunc = new ArrayList<HashFunction>();
        for (int i = 0; i < k; ++i)
            hashFunc.add(new HashFunction(100000 + i, 2 * i + 3));
        bits = new int[100000 + k];
    }

    public void add(String word) {
        // Write your code here
        for (int i = 0; i < k; ++i) {
            int position = hashFunc.get(i).hash(word);
            bits[position] += 1;
        }
    }

    public void remove(String word) {
        // Write your code here
        for (int i = 0; i < k; ++i) {
            int position = hashFunc.get(i).hash(word);
            bits[position] -= 1;
        }
    }

    public boolean contains(String word) {
        // Write your code here
        for (int i = 0; i < k; ++i) {
            int position = hashFunc.get(i).hash(word);
            if (bits[position] <= 0)
                return false;
        }
        return true;
    }
}

看看其他的Bloom fliter的文章再来看我的代码就还理解多了
不懂可以交流哦!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值