我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++ BloomFilter布隆过滤器如何应用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++ BloomFilter布隆过滤器如何应用

这篇“C++ BloomFilter布隆过滤器如何应用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++ BloomFilter布隆过滤器如何应用”文章吧。

    一、布隆过滤器概念

    布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中。此种方式不仅可以提升查询效率,也可以节省大量的内存空间 .

    位图的优点是节省空间,快,缺点是要求范围相对集中,如果范围分散,空间消耗上升,同时只能针对整型,字符串通过哈希转化成整型,再去映射,对于整型没有冲突,因为整型是有限的,映射唯一的位置,但是对于字符串来说,是无限的,会发生冲突,会发生误判:此时的情况的是不在是正确的,在是不正确的,因为可能不来是不在的,但是位置跟别人发生冲突,发生误判

    此时布隆过滤器就登场了,可以降低误判率:让一个值映射多个位置,但是并不是消除误判

    C++ BloomFilter布隆过滤器如何应用

    可能还是会出现误判:

    C++ BloomFilter布隆过滤器如何应用

    虽然布隆过滤器还是会出现误判,因为这个数据的比特位被其他数据所占,但是判断一个数据不存在是准确,不存在就是0!

    布隆过滤器改进:映射多个位置,降低误判率(位置越多,消耗也越多)

    如果布隆过滤器长度比较小,比特位很快会被占为1,误判率自然会上升,所以布隆过滤器的长度会影响误判率,理论上来说,如果一个值映射的位置越多,则误判的概率越小,但是并不是位置越多越好,空间也会消耗:大佬们自然也能够想得到,所以有公式:

    C++ BloomFilter布隆过滤器如何应用

    我们可以来估算一下,假设用 3 个哈希函数,即K=3,ln2 的值我们取 0.7,那么 m 和 n 的关系大概是 m = n×k/ln2=4.2n ,也就是过滤器长度应该是插入元素个数的 4 -5倍

    二、布隆过滤器应用

    不需要一定准确的场景。比如游戏注册时候的昵称的判重:如果不在那就是不在,没被使用,在的话可能会被误判。

    提高查找效率:客户端中查找一个用户的ID与服务器中的是否相同,在增加一层布隆过滤器提高查找效率:

    C++ BloomFilter布隆过滤器如何应用

    三、布隆过滤器实现

    布隆过滤器的插入元素可能是字符串,也可能是其他类型,只要提供对应的哈希函数将该类型的数据转换成整型就可以了。

    一般情况下布隆过滤器都是用来处理字符串的,所以布隆过滤器可以实现为一个模板类,将模板参数 T 的缺省类型设置为 string:

    template <size_t N,size_t X = 5,class K=string,class HashFunc1 = BKDRHash,class HashFunc2 = APHash,class HashFunc3 = DJBHash>class BloomFilter{    public:    private:bitset<N * X> _bs;};

    这里布隆过滤器提供三个哈希函数,由于布隆过滤器一般处理的是字符串类型的数据,所以我们默认提供几个将字符串转换成整型的哈希函数:选取综合评分最高的 BKDRHash、APHash 和 DJBHash这三种哈希算法:

       struct BKDRHash{size_t operator()(const string& key){size_t hash = 0;for (auto ch : key){hash *= 131;hash += ch;}return hash;}};struct APHash{size_t operator()(const string& key){size_t hash = 0;int i = 0;for (auto ch : key){if ((i & 1) == 0){hash ^= ((hash << 7) ^ (ch) ^ (hash >> 3));}else{hash ^= (~((hash << 11) ^ (ch) ^ (hash >> 5)));}++i;}return hash;}};struct DJBHash{size_t operator()(const string& key){size_t hash = 5318;for (auto ch : key){hash += (hash << 5) + ch;}return hash;}};

    1.插入

    布隆过滤器复用bitset的 set 接口用于插入元素,插入元素时,我们通过上面的三个哈希函数分别计算出该元素对应的三个比特位,然后在位图中设置为1即可:

            void set(const K& key){size_t hash2 = HashFunc1()(key) % (N * X);size_t hash3 = HashFunc2()(key) % (N * X);size_t hash4 = HashFunc3()(key) % (N * X);_bs.set(hash2);_bs.set(hash3);_bs.set(hash4);_bs.set(hash5);}

    2.查找

    通过三个哈希函数分别算出对应元素的三个哈希地址,得到对应的比特位,然后去判断这三个比特位是否都被设置成了1

    如果出现一个比特位未被设置成1说明该元素一定不存在,也就是如果一个比特位为0就是false;而如果三个比特位全部都被设置,则return true表示该元素已经存在(注:可能会出现误判)

            bool test(const K& key){size_t hash2 = HashFunc1()(key) % (N * X);if (!_bs.test(hash2)){return false;}size_t hash3 = HashFunc2()(key) % (N * X);if (!_bs.test(hash3)){return false;}size_t hash4 = HashFunc3()(key) % (N * X);if (!_bs.test(hash4)){return false;}return true;}

    3.删除

    布隆过滤器一般没有删除,因为布隆过滤器判断一个元素是会存在误判,此时无法保证要删除的元素在布隆过滤器中,如果此时将位图中对应的比特位清0,就会影响到其他元素了:

    C++ BloomFilter布隆过滤器如何应用

    这时候我们只需要在每个比特位加一个计数器,当存在插入操作时,在计数器里面进行 ++,删除后对该位置进行 -- 即可

    C++ BloomFilter布隆过滤器如何应用

    但是布隆过滤器的本来目的就是为了提高效率和节省空间,在每个比特位增加额外的计数器,空间消耗那就更多了

    四、布隆过滤器优缺

    \1. 增加和查询元素的时间复杂度为:O(K), (K为哈希函数的个数,一般比较小),与数据量大小无关

    \2. 哈希函数相互之间没有关系,方便硬件并行运算

    \3. 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势

    \4. 在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势

    \5. 数据量很大时,布隆过滤器可以表示全集,其他数据结构不能

    \6. 使用同一组散列函数的布隆过滤器可以进行交、并、差运算

    \1. 有误判率,不能准确判断元素是否在集合中(补救方法:再建立一个白名单,存储可能会误判的数据)

    \2. 不能获取元素本身

    \3. 一般情况下不能从布隆过滤器中删除元素

    五、结语

    给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法?

    近似算法:利用布隆过滤器,交集的就一定会进去,但是可能会存在误判:不同的也会进去,这是近似

    精准算法:query一般是查询指令,比如可能是网络请求,或者是一个数据库sql语句

    100亿个query,假设平均每个query是50byte,则100亿个query那就是合计500GB

    相同的query,是一定进入相同编号的小文件,再对这些文件放进内存的两个set中,编号相同的Ai和Bi小文件找交集即可

    C++ BloomFilter布隆过滤器如何应用

    以上就是关于“C++ BloomFilter布隆过滤器如何应用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    C++ BloomFilter布隆过滤器如何应用

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    C++ BloomFilter布隆过滤器如何应用

    这篇“C++ BloomFilter布隆过滤器如何应用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++ BloomFil
    2023-07-05

    C++BloomFilter布隆过滤器应用及概念详解

    布隆过滤器是由布隆(BurtonHowardBloom)在1970年提出的一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你“某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中
    2023-03-08

    Redis中Bloomfilter布隆过滤器的学习

    布隆过滤器是一个非常长的二进制向量和一系列随机哈希函数的组合,可用于检索一个元素是否存在,本文就详细的介绍一下Bloomfilter布隆过滤器,具有一定的参考价值,感兴趣的可以了解一下
    2022-12-14

    Java的布隆过滤器如何实现

    今天小编给大家分享一下Java的布隆过滤器如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。BitMap现代计算机用二进
    2023-06-29

    SpringBoot+Redis如何实现布隆过滤器

    小编给大家分享一下SpringBoot+Redis如何实现布隆过滤器,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!简述关于布隆过滤器的详细介绍,我在这里就不再赘述一遍了我们首先知道:BloomFilter使用长度为m bi
    2023-06-29

    C++位图,哈希切分与布隆过滤器怎么应用

    本篇内容主要讲解“C++位图,哈希切分与布隆过滤器怎么应用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++位图,哈希切分与布隆过滤器怎么应用”吧!一、位图1、位图的概念所谓位图,就是用每一位
    2023-07-05

    Java布隆过滤器怎么使用

    本文小编为大家详细介绍“Java布隆过滤器怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java布隆过滤器怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。通常你判断某个元素是否存在用的是什么?很多
    2023-06-29

    Java中的布隆过滤器原理实现和应用

    Java中的布隆过滤器是一种基于哈希函数的数据结构,能够高效地判断元素是否存在于一个集合中。它广泛应用于缓存、网络协议、数据查询等领域,在提高程序性能和减少资源消耗方面具有显著优势
    2023-05-17

    redis布隆过滤器的作用是什么

    Redis布隆过滤器是一种数据结构,用于快速判断一个元素是否存在于一个集合中。它可以高效地判断一个元素是否可能在集合中,但无法确保元素一定在集合中或者排除元素已经在集合中。布隆过滤器通常用于减少对数据库的查询次数,节省资源和时间。常见的应用
    redis布隆过滤器的作用是什么
    2024-04-09

    C++哈希应用之位图,哈希切分与布隆过滤器详解

    这篇文章主要为大家详细介绍了C++哈希应用中的位图、哈希切分与布隆过滤器,文中的示例代码讲解详细,具有一定的学习价值,需要的可以参考一下
    2023-05-14

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录