通过实例解析布隆过滤器工作原理及实例

 更新时间:2021年1月15日 13:18  点击:1681

布隆过滤器

布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 “一定不存在或者可能存在”。

相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。

布隆过滤器的工作原理

假设一个长度为m的bit类型的数组,即数组中每个位置只占一个bit,每个bit只有两种状态:0,1,所有bit的初始状态都为0。

再假设一共有k个哈希函数,这些函数的输出域大于或者等于m,并且这些哈希函数,彼此之间相互独立,每个哈希函数计算出来的结果是独立的,可能相同也可能不相同,对每一个计算出来的结果都对m取余(%m),然后再将数组下标位置置为1。

我们这里假设m为13,k为3的布隆过滤器,来看看布隆过滤器的工作原理:

当我们要映射一个值到布隆过滤器时,首先计算三个哈希函数的值,然后对13取余,映射到对应位中,图中映射到2,6,10,这样我们就完成了一个值的映射。

那么怎么判断一个值是否存在,当一个值输入时,通过三个哈希函数,然后取余,我们就可以得到对应的三个位置,我们只需要判断这三个位置是否都为1,如果都为1,则该值存储,反之不存在。

但是有一个特殊情况,前面说了不同的哈希函数可能计算可能相同也可能不相同,而且不同的哈希函数对不同的值计算出来的值可能一样,这就造成一个结果,一个值通过哈希和取余得到的位置,早就被其它值给置1了,当我们存储的值过多,而这个bit数组过小,都会造成这种情况更多的发生,一个值明明不存在,而它的所有位置早就被其它不同值置1,造成了误判,这里就对布隆过滤器提出了一个指标:失误率p。

在同样数据规模下,不同大小的bit数组及不同数量k的哈希函数对误判率的结果:

如何选取最合适的m(bit数组的大小)及k(哈希函数的数量),在已知n(需要映射的值得数量)及失误率p的情况下:

m的选取:

k的选取:

给个例子:假设n=100亿,p=0.01%

通过公式计算出来m=19.19n,向上取整位20n,即2000亿个bit,也就是25gb。

通过公式计算出来k=14。

计算真实失误率:

根据公式计算出来的真实失误率位0.006%。

c语言实现

#include <stdio.h>

#define Size 100
#define BitSIZE Size * 4 * 8
//c语言中一个整型数据类型4个字节 
int bit[Size]={0};

  
int SDBMHash(char *str)
{
  unsigned int hash = 0;
  while (*str)
  {
    // equivalent to: hash = 65599*hash + (*str++);
    hash = (*str++) + (hash << 6) + (hash << 16) - hash;
  }
  return (hash & 0x7FFFFFFF);
}

int RSHash(char *str)
{
  unsigned int b = 378551;
  unsigned int a = 63689;
  unsigned int hash = 0;
 
  while (*str)
  {
    hash = hash * a + (*str++);
    a *= b;
  }
 
  return (hash & 0x7FFFFFFF);
}

int JSHash(char *str)
{
  unsigned int hash = 1315423911;
 
  while (*str)
  {
    hash ^= ((hash << 5) + (*str++) + (hash >> 2));
  }
 
  return (hash & 0x7FFFFFFF);
}


void Insert(int hash){
  
  //int value = hash%BitSIZE; ([0-3200]范围的值)
  //int listindex = value / 32; (listindex为数组下标)
  //int bitindex = value % 32; (某位)
  
  int value = hash%BitSIZE;
  int listindex = value / 32;
  int bitindex = value % 32;
  int temp = bit[listindex];
  bit[listindex] = bit[listindex] & (1 << bitindex);
  bit[listindex] = bit[listindex] | temp;
}

int Serach(int hash){
  int value = hash%BitSIZE;
  int listindex = value / 32;
  int bitindex = value % 32;
  if (bit[listindex] | (1 << bitindex)){
    return 1;
  }
  return 0;
}



int main () {
  
  char str1[] = "abc123";
  
  //在布隆过滤器中插入某值
  Insert(SDBMHash(str1));
  Insert(RSHash(str1));
  Insert(JSHash(str1));
  
  //在布隆过滤器中判断某值是否存在
  int i = 0;
  i = i+Serach(SDBMHash(str1));
  i = i+Serach(RSHash(str1));
  i = i+Serach(JSHash(str1));
  if(i == 3){
    printf("字符串:%s存在\n",str1);
  }

  return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。

[!--infotagslink--]

相关文章

  • nestjs中异常过滤器Exceptionfilter的具体使用

    这篇文章主要介绍了nestjs中异常过滤器Exceptionfilter的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-07
  • 详解Tomcat常用的过滤器

    过滤器Filter是定义于tomcat的servlet-api.jar中的一个接口,接口路径为javax.servlet.Filter。tomcat过滤器采用了典型的过滤器设计模式,过滤器链FilterChain由tomcat维持,链条是可以支持多个过滤器的...2021-06-26
  • Vue封装全局过滤器Filters的步骤

    这篇文章主要介绍了Vue封装全局过滤器Filters的步骤,通过封装vue全局过滤器实现filters的统一管理。感兴趣的朋友可以了解下...2020-09-16
  • vue 将多个过滤器封装到一个文件中的代码详解

    这篇文章主要介绍了vue 将多个过滤器封装到一个文件中实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧...2020-09-05
  • Vue.js学习之过滤器详解

    过滤器,本质上就是一个函数。其作用在于用户输入数据后,它能够进行处理,并返回一个数据结果。下面这篇文章主要给大家介绍了Vue.js中过滤器的相关资料,需要的朋友可以参考借鉴,一起来看看吧。...2017-01-26
  • Vue的全局过滤器和私有过滤器的实现

    这篇文章主要介绍了Vue的全局过滤器和私有过滤器的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-20
  • vue3删除过滤器的原因

    去年,vue3出来了。增加了很多新功能,但是也删掉了一些功能。比如删掉了vue2中的过滤器filter功能。与此同时,官方建议:用方法调用或计算属性替换过滤器。本文将分析vue3删除过滤器的原因及如何用其他方法实现过滤器的功能...2021-05-13
  • AngularJS 过滤器(自带和自建)详解

    这篇文章主要介绍了AngularJS 过滤器(自带和自建)详解的相关资料,需要的朋友可以参考下...2016-10-03
  • AngularJS实现用户登录状态判断的方法(Model添加拦截过滤器,路由增加限制)

    这篇文章主要介绍了AngularJS实现用户登录状态判断的方法,通过Model添加拦截过滤器,路由增加限制实现针对登陆状态的判断功能,需要的朋友可以参考下...2017-01-09
  • vue货币过滤器的实现方法

    这篇文章主要为大家详细介绍了vue货币过滤器的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2017-04-03
  • asp.net core MVC 全局过滤器之ExceptionFilter过滤器(1)

    这篇文章主要为大家详细介绍了asp.net core MVC 全局过滤器之ExceptionFilter过滤器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
  • AngularJS过滤器详解及示例代码

    本文主要介绍AngularJS过滤器,这里整理了详细的资料和提供了示例代码及实例效果图,有兴趣的小伙伴可以参考下...2016-08-24
  • vue过滤器实现日期格式化的案例分析

    这篇文章主要介绍了vue过滤器实现日期格式化的案例分析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-02
  • 布隆过滤器的原理以及java 简单实现

    这篇文章主要介绍了布隆过滤器的原理以及java 简单实现,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下...2020-11-25
  • smarty高级特性之过滤器的使用方法

    这篇文章主要介绍了smarty高级特性之过滤器的使用方法,结合实例形式分析了smarty过滤器的相关使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2015-12-27
  • Go语言实现布谷鸟过滤器的方法

    这篇文章主要介绍了Go语言实现布谷鸟过滤器的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-01
  • Java中使用Filter过滤器的方法

    Filter过滤器是javaWeb层面的,它跟Servlet类似,每次前端请求,首先进入的是过滤器,我们必须实现Filter接口,重写三个方法,才能使用Filter过滤器,需要的朋友可以参考下...2021-06-28
  • vue通过过滤器实现数据格式化

    这篇文章主要介绍了vue通过过滤器实现数据格式化的方法,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-20
  • 详解AngularJS Filter(过滤器)用法

    这篇文章主要介绍了AngularJS的filter,中文名“过滤器”是用来过滤变量的值,或者格式化输出,得到自己所期望的结果或格式的东东,的相关资料,需要的朋友可以参考下...2015-12-29
  • java 使用过滤器实现登录拦截处理

    这篇文章主要介绍了java 使用过滤器实现登录拦截处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-27