BloomFilter过滤器代码原理介绍

BloomFilter过滤器代码原理介绍

通过多个hash函数的使用可以减少hash冲突的出现。

package com.xdclass.mobile.xdclassmobileredis.controller;
import java.util.BitSet;
//传统的Bloom filter 不支持从集合中删除成员。
//Counting Bloom filter由于采用了计数,因此支持remove操作。
//基于BitSet来实现,性能上可能存在问题
public class SimpleBloomFilter {
    //DEFAULT_SIZE为2的25次方
    private static final int DEFAULT_SIZE = 2 << 24;
    /* 不同哈希函数的种子,一般应取质数,seeds数据共有7个值,则代表采用7种不同的HASH算法 */
    private static final int[] seeds = new int[] { 5, 7, 11, 13, 31, 37, 61 };
    //BitSet实际是由“二进制位”构成的一个Vector。假如希望高效率地保存大量“开-关”信息,就应使用BitSet.
    //BitSet的最小长度是一个长整数(Long)的长度:64位
    private BitSet bits = new BitSet(DEFAULT_SIZE);
    /* 哈希函数对象 */
    private SimpleHash[] func = new SimpleHash[seeds.length];

    public static void main(String[] args) {
        String value = "stone2083@yahoo.cn";
        //定义一个filter,定义的时候会调用构造函数,即初始化七个hash函数对象所需要的信息。
        SimpleBloomFilter filter = new SimpleBloomFilter();
        //判断是否包含在里面。因为没有调用add方法,所以肯定是返回false
        System.out.println(filter.contains(value));
        filter.add(value);
        System.out.println(filter.contains(value));
    }
    //构造函数
    public SimpleBloomFilter() {
        for (int i = 0; i < seeds.length; i++) {
            //给出所有的hash值,共计seeds.length个hash值。共7位。
            //通过调用SimpleHash.hash(),可以得到根据7种hash函数计算得出的hash值。
            //传入DEFAULT_SIZE(最终字符串的长度),seeds[i](一个指定的质数)即可得到需要的那个hash值的位置。
            func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);
        }
    }

    // 将字符串标记到bits中,即设置字符串的7个hash值函数为1
    public void add(String value) {
        for (SimpleHash f : func) {
            bits.set(f.hash(value), true);
        }
    }

    //判断字符串是否已经被bits标记
    public boolean contains(String value) {
        //确保传入的不是空值
        if (value == null) {
            return false;
        }
        boolean ret = true;
        //计算7种hash算法下各自对应的hash值,并判断
        for (SimpleHash f : func) {
            //&&是boolen运算符,只要有一个为0,则为0。即需要所有的位都为1,才代表包含在里面。
            //f.hash(value)返回hash对应的位数值
            //bits.get函数返回bitset中对应position的值。即返回hash值是否为0或1。
            ret = ret && bits.get(f.hash(value));
        }
        return ret;
    }
    /* 哈希函数类 */
    public static class SimpleHash {
        //cap为DEFAULT_SIZE的值,即用于结果的最大的字符串长度。
        //seed为计算hash值的一个给定key,具体对应上面定义的seeds数组
        private int cap;
        private int seed;

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

        //计算hash值的具体算法,hash函数,采用简单的加权和hash
        public int hash(String value) {
            //int的范围最大是2的31次方减1,或超过值则用负数来表示
            int result = 0;
            int len = value.length();
            for (int i = 0; i < len; i++) {
                //数字和字符串相加,字符串转换成为ASCII码
                result = seed * result + value.charAt(i);
                //System.out.println(result+"--"+seed+"*"+result+"+"+value.charAt(i));
            }
            //  System.out.println("result="+result+";"+((cap - 1) & result));
            //  System.out.println(414356308*61+'h');  执行此运算结果为负数,为什么?
            //&是java中的位逻辑运算,用于过滤负数(负数与进算转换成反码进行)。
            return (cap - 1) & result;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
布隆过滤器是一种非常高效的数据结构,用于判断某个元素是否存在于一个集合中。它的基本原理是使用多个哈希函数对元素进行哈希,然后将哈希结果映射到一个位数组中的若干个位置,将这些位置标记为1。当需要查询某个元素是否在集合中时,将该元素进行哈希,判断哈希结果映射到的位数组上的值是否都为1,如果都为1,则说明该元素可能存在于集合中,但如果有任何一个位置为0,则说明该元素一定不存在于集合中。 布隆过滤器的应用场景非常广泛,例如网络爬虫中的URL去重、拼写检查、垃圾邮件过滤等。它的主要优点是占用空间非常小,而且查询速度非常快。 下面是一个简单的布隆过滤器的实现示例: ```python import hashlib class BloomFilter: def __init__(self, m, k): self.m = m # 位数组的长度 self.k = k # 哈希函数的个数 self.bit_array = [0] * m # 初始化位数组 def add(self, key): for i in range(self.k): # 使用不同的哈希函数进行哈希 hash_val = int(hashlib.md5(str(key).encode('utf-8') + str(i).encode('utf-8')).hexdigest(), 16) # 将哈希结果映射到位数组上的若干个位置 pos = hash_val % self.m self.bit_array[pos] = 1 def contains(self, key): for i in range(self.k): hash_val = int(hashlib.md5(str(key).encode('utf-8') + str(i).encode('utf-8')).hexdigest(), 16) pos = hash_val % self.m if self.bit_array[pos] == 0: return False return True ``` 在上述代码中,我们使用了MD5哈希函数对字符串进行哈希,产生一个128位的哈希值,并将其转换为一个整数。然后,我们将这个整数对位数组的长度取模,得到一个在0到`m-1`之间的整数,将位数组上对应的位置标记为1。在查询元素是否存在于集合中时,我们同样对该元素进行k次哈希,并检查位数组上对应的位置是否都为1。如果有任何一个位置为0,则说明该元素一定不存在于集合中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值