[C++]哈希应用-布隆过滤器快速入门

布隆过滤器

布隆过滤器(Bloom Filter)是一个由布隆在1970年提出的概率型数据结构,它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器的主要特点是高效的插入和查询,可以用于检索一个元素是否在一个集合中。

原理:

  • 布隆过滤器是采用位图的方式来记录数据的存在与否
  • 将要存储的数据同时映射到位图的多个节点上
  • 当寻找数据时,只需将要找的数据进行映射,观察全部映射节点的情况,就可以判断数据存在与否

其核心功能如下(此处以数据库使用布隆过滤器为例):

在这里插入图片描述

解释:

对于一个数据的查找,会先去布隆过滤器中进行多个映射点的查询。会有如下情况发生:

  1. 只有当每个映射点都存在(对应位置为1)的时候,才能说明该数据可能存在,下一步就去Database中进一步确认(因为冲突的原因,所以可能某个数据的每个映射点虽然都为1,但是该数据并不存在其中)。
  2. 如果有任何一个映射点不存在(对应位置为0)的时候,就说明该数据并不在存储空间内。

如何选择映射

布隆的核心就是最大限度减少冲突问题,进而在高查找效率的情况下,减少寻找错误的可能性!

现在提出一个问题:如果我只采用一个映射(每个数据只映射到一个位图节点上),由于哈希的局限性以及开辟空间的有限性,就会出现多个数据映射到同一个位置上

所以布隆过滤器就采用了多映射的方案(即一个值映射到多个位图节点上),大大缩小了冲突的可能性

优点:

  1. 多于不同的数据,他们在某个哈希函数下可能映射到了同一个位置,但是对于多个映射全相同的概率极小,这就使得哈希冲突变小
  2. 由于数据的查询一般采用轮询的方式(或者树形结构)导致时间复杂度较大,而布隆过滤器的查询效率是大O(1)(忽略极个别的全冲突情况)

缺点:

  1. 不存在漏报,但存在误报(即对于数据存在的判断有失准确性)。但严格来说该缺点不算大事
  2. 不能在布隆过滤器中删除元素,因为这会影响到别的与该位图节点有关联的数据(但可以改造他,使他可以实现删除操作)

哈希函数的选择:

可以采用BKDRAP等哈希函数

选择的哈希函数的前提是:需要保证映射后的值能合理放到位图中的对应位置上(如果你映射出来一个:164gxap3,那么你该放入位图中的哪个位置呢?是吧)

应用场景

  1. 快速检索元素:布隆过滤器能够快速地检索一个元素是否在一个集合中,而无需访问整个集合。这大大提高了查询效率,尤其是在处理大数据集时。
  2. 网页URL去重:在搜索引擎或爬虫系统中,布隆过滤器可以用于过滤已经访问过的网页URL,避免重复访问和存储。
  3. 垃圾邮件过滤:布隆过滤器可以存储已知的垃圾邮件发送者的地址或特征,当接收到新邮件时,可以通过检查邮件地址或内容是否在布隆过滤器中来判断其是否为垃圾邮件。
  4. 数据库查询优化:在数据库中,布隆过滤器可以用于减少不必要的磁盘查找操作。例如,当查询一个不存在的行或列时,布隆过滤器可以快速判断该数据是否存在于数据库中,从而避免不必要的磁盘访问。
  5. 恶意代码检测:在网络安全领域,布隆过滤器可以用于检测恶意代码的僵尸网络或分析不断变化的市场数据。通过存储已知的恶意代码特征或行为模式,布隆过滤器可以快速判断新发现的代码是否为恶意代码。
  6. 生物信息学应用:布隆过滤器可以用于快速查找DNA测序数据中的基因序列,以及在其他生物学和遗传学领域如蛋白质组学、转录组学和基因组学等进行数据分析。
  7. 非结构化大数据分析:在企业数据分析中,布隆过滤器可以帮助企业快速检测网站中的指定元素(如URL中的关键字、用户搜索的关键字等),从而找出其中的趋势和模式,帮助企业更好地投资和发展。
  8. 机器学习应用:在机器学习领域,布隆过滤器可以用于快速处理海量数据,提取特征并构建模型。由于布隆过滤器的快速查询能力,它可以大大提高模型训练和预测的效率。

代码实现以及成果演示

存储的元素:“hello”, “world”, “你好”, “no thank”, “why”, “4”, “-78”

查找的元素:“world”,“你好”,“早上好”,“no thank”,“8”,“4”,“0”,“-78”

分别采用了BKDR、AP、DJB三个哈希函数

uint64_t BKDR_Hash(const char* str) {
    uint64_t seed = 131; // 31 131 1313 13131 131313 etc..  
    uint64_t hash = 0;

    while (*str) {
        hash = hash * seed + (*str++);
    }

    return hash;
}
uint64_t AP_Hash(const char* str)
{
    uint64_t hash = 0;
    int i;

    for (i = 0; *str; i++)
    {
        if ((i & 1) == 0)
        {
            hash ^= ((hash << 7) ^ (*str++) ^ (hash >> 3));
        }
        else
        {
            hash ^= (~((hash << 11) ^ (*str++) ^ (hash >> 5)));
        }
    }

    return (hash & 0x7FFFFFFF);
}
uint64_t DJB_Hash(const char* str)
{
    uint64_t hash = 5381;

    while (*str)
    {
        hash += (hash << 5) + (*str++);
    }

    return (hash & 0x7FFFFFFF);
}
int main()
{
    bitset<10000> st;
    vector<string> vstr{"hello", "world", "你好", "no thank", "why", "4", "-78"};

    for (int i = 0; i < vstr.size(); i++)
    {
        st.set(BKDR_Hash(vstr[i].c_str()) % st.size());
        st.set(AP_Hash(vstr[i].c_str()) % st.size());
        st.set(DJB_Hash(vstr[i].c_str()) % st.size());
    }
    vector<string> vfind{"world","你好","早上好","no thank","8","4","0","-78"};
    for (int i = 0; i < vfind.size(); i++)
    {
        cout << vfind[i];
        if (st[BKDR_Hash(vfind[i].c_str()) % st.size()]
            && st[AP_Hash(vfind[i].c_str()) % st.size()]
            && st[DJB_Hash(vfind[i].c_str()) % st.size()])
        {
            cout << " exist" << endl;
        }
        else
        {
            cout << " not exixt" << endl;
        }
    }
	return 0;
}

查找结果:

world exist
你好 exist
早上好 not exixt
no thank exist
8 not exixt
4 exist
0 not exixt
-78 exist

优化成可实现删除操作

对于前面的布隆过滤器的写法,有一个很明显的问题:对于数据的删除是不可实现的,因为对任意一个数据映射位置的删除,由于哈希冲突,都可能导致影响到别的数据的映射关系

所以我们采用引用计数+扩展位图的方式来实现删除操作,具体操作如下:

采用引用计数的方案,对每一个哈希映射值都采用引用计数。每新增一个映射关系就++,减少一个映射关系就- -

如此一来,对位图也需要有所更改:增大位图空间开销,比如用8个bit表示一个映射关系,而在这8个bit中就可以用引用计数实现0-255的可映射数量

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/605033.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

box-decoration-break 使用介绍

box-decoration-break属性的使用 一、定义 box-decoration-break是CSS片段模块&#xff08;CSS Fragmentation Module Level 3&#xff09;中的一个属性&#xff0c;主要用于指定背景&#xff08;background&#xff09;、内边距&#xff08;padding&#xff09;、边框&#…

K邻近算法

简介 介绍了非常简单的算法&#xff1a;K邻近算法&#xff0c;即KNN。 基本介绍 K-近邻算法&#xff08;K-Nearest Neighbors&#xff0c;简称KNN&#xff09;是一种基本且广泛应用的监督学习算法&#xff0c;主要用于分类和回归任务。 工作原理非常简答直观&#xff1a;所谓…

nginx: [emerg] invalid number of arguments in “alias“ directive in D:\nginx

问题背景 最近在配置一个nginx的配置&#xff0c;但是reload的时候遇到了以下报错 D:\nginx>nginx -s reload nginx: [emerg] invalid number of arguments in "alias" directive in D:\nginx/conf /nginx.conf:113 解决方案 关于“alias”指令中的参数数量错误…

十二届蓝桥杯Python组1月中/高级试题 第一题

** 十二届蓝桥杯Python组1月中/高级试题 第一题 第一题&#xff08;难度系数2&#xff0c;18 个计分点&#xff09; 编程实现&#xff1a; 输入一个字符串&#xff0c;输出这个字符串的最后一个字符。 输入描述&#xff1a;输入一个字符串 输出描述&#xff1a;输出这个字符串…

OpenCV单窗口并排显示多张图片

OpenCV单窗口并排显示多张图片 效果代码 PS&#xff1a;本例的代码适合图片的宽度和高度都相同。 效果 原始三张图片&#xff1a; 合并显示&#xff1a; 代码 import cv2 import numpy as npdef opencv_multi_img():# 读取图片img1 cv2.imread(saw_1.jpeg)img2 cv2.im…

2024软件测试自动化面试题(含答案)

1.如何把自动化测试在公司中实施并推广起来的&#xff1f; 选择长期的有稳定模块的项目 项目组调研选择自动化工具并开会演示demo案例&#xff0c;我们主要是演示selenium和robot framework两种。 搭建自动化测试框架&#xff0c;在项目中逐步开展自动化。 把该项目的自动化…

实验五 Spark Structured Streaming编程实践

一、编写程序 (1). 按照tag分组统计生成的日志数。 在新开的终端内输入 vi spark_exercise_testsyslog1.py &#xff0c;贴入如下代码并运行。运行之前需要关闭“tail终端”内的tail命令并重新运行tail命令&#xff0c;否则多次运行测试可能导致没有新数据生成。 #!/usr/bin…

Rust使用HashSet对Vec类型的元素进行去重

在Rust语言中&#xff0c;对Vec类型的元素进行去重&#xff0c;一种常见的方法是使用一个HashSet来帮助我们快速检查元素是否已经存在。以下是使用HashSet对Vec进行去重的示例代码&#xff1a; use std::collections::HashSet;fn main() {let vec_numbers vec![1, 2, 2, 3, 4…

Marin说PCB之国产电源芯片方案 ---STC2620Q

随着小米加入的造车大家庭&#xff0c;让这个本来就卷的要死的造车大家庭更加卷了。随之带来的蝴蝶效应就是江湖上各个造成门派都开始了降本方案的浪潮啊&#xff0c;开始打响价格战了。各家的新能源车企也是不得不开始启动了降本方案的计划了&#xff0c;为了应对降价的浪潮。…

手游广告归因新选择:Xinstall助力精准衡量投放效果

在手游市场竞争日益激烈的今天&#xff0c;广告主们面临着如何精准衡量广告投放效果的难题。手游广告归因平台的出现&#xff0c;为广告主们提供了一种全新的解决方案。而Xinstall&#xff0c;作为其中的佼佼者&#xff0c;正以其独特的优势&#xff0c;助力广告主们破解这一难…

【AI大模型】AI大模型热门关键词解析与核心概念入门

&#x1f680; 作者 &#xff1a;“大数据小禅” &#x1f680; 文章简介 &#xff1a;本专栏后续将持续更新大模型相关文章&#xff0c;从开发到微调到应用&#xff0c;需要下载好的模型包可私。 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 目…

SPSS多元线性回归

&#xff08;要满足&#xff09;模型的假设条件需要对数据进行怎样处理&#xff1f;&#xff1f; 为了使数据满足多元线性回归的条件&#xff0c;通常需要进行以下预处理步骤&#xff1a; 1. 数据清洗&#xff1a;处理缺失值、异常值和重复值&#xff0c;确保数据质量。 2. 特…

python-oracledb 已率先支持 Oracle 23ai

python-oracledb 介绍 python-oracledb (以下简称 oracledb) 是 Python cx_Oracle 驱动程序的新名称&#xff0c;如果你仍在使用 cx_Oracle&#xff0c;建议升级到最新版本的 oracledb。 oracledb 驱动程序是一个开源模块&#xff0c;使 Python 程序能够访问 Oracle 数据库。默…

美业SaaS系统多门店收银系统源码-【卡升组合促销规则】讲解分享

美业管理系统源码 博弈美业SaaS系统 连锁多门店美业收银系统源码 多门店管理 / 会员管理 / 预约管理 / 排班管理 / 商品管理 / 促销活动 PC管理后台、手机APP、iPad APP、微信小程序 1、什么是卡升组合促销&#xff1f; 原价购买的卡项&#xff0c;卡状态正常的情况下&…

分红76.39亿,分红率再创新高,成长活力无限的伊利带来丰厚回报

伊利47万股东&#xff0c;又等来了一个好消息。 4月29日&#xff0c;伊利股份发布2023年报&#xff0c;实现营业总收入1261.79亿元&#xff0c;归母净利润104.29亿元&#xff0c;双创历史新高&#xff0c;实现连续31年稳健增长。 在递交亮眼成绩单的同时&#xff0c;乳业巨头伊…

MyBatis的其他查询操作

前言&#xff1a;在上篇博客介绍了MyBatis的一些增删改查操作&#xff0c;接下来介绍其他查询操作 目录 1 其他查询操作 1.1 多表查询 1.1.1 准备工作 1.1.2 数据查询 1.2 #{}和${} 1.2.1 #{}和${}使用 1.2.2 #{}和${}的区别 1.3 排序功能 1.4 like查询 2 数据库连接池 2.1 …

C++反射之检测struct或class是否实现指定函数

目录 1.引言 2.检测结构体或类的静态函数 3.检测结构体或类的成员函数 3.1.方法1 3.2.方法2 1.引言 诸如Java, C#这些语言是设计的时候就有反射支持的。c没有原生的反射支持。并且&#xff0c;c提供给我们的运行时类型信息非常少&#xff0c;只是通过typeinfo提供了有限的…

【吃透Java手写】1- Spring(上)-启动-扫描-依赖注入-初始化-后置处理器

【吃透Java手写】Spring&#xff08;上&#xff09;启动-扫描-依赖注入-初始化-后置处理器 1 准备工作1.1 创建自己的Spring容器类1.2 创建自己的配置类 ComponentScan1.3 ComponentScan1.3.1 Retention1.3.2 Target 1.4 用户类UserService Component1.5 Component1.6 测试类 2…

AI实景自动无人直播软件:引领直播行业智能化革命;提升直播效果,无人直播软件助力智能讲解

随着科技的快速发展&#xff0c;AI实景自动无人直播软件正在引领直播行业迈向智能化革命。它通过智能讲解、一键开播和智能回复等功能&#xff0c;为商家提供了更高效、便捷的直播体验。此外&#xff0c;软件还支持手机拍摄真实场景或搭建虚拟场景&#xff0c;使直播画面更好看…

Unity 性能优化之动态批处理(四)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、动态合批是什么&#xff1f;二、使用动态批处理1.打开动态合批2.满足条件 三、检查动态合批是否成功五、动态合批弊端总结 前言 动态批处理是常用优…
最新文章