哈希应用 | 布隆过滤器概念 | 代码实现 | 哈希切割

文章目录

        • 1.布隆过滤器
          • 1.1.布隆过滤器的基本概念
          • 1.2.代码实现
          • 1.3.测试代码分析误判率
          • 1.4.布隆过滤器的优点
          • 1.5.关于几道面试题

关于位图:往期分析的 博客链接

1.布隆过滤器
1.1.布隆过滤器的基本概念

布隆过滤器的引出

位图使用1个比特位 + 直接定址法,来存储整数,但是如果用位图来存放字符串甚至是对象,那么它就无法胜任!假设下面的两个字符串通过计算映射到相同的位置,这里是两个字符串还好,万一是很多的字符串都冲突,这样位图就处理不了。

在这里插入图片描述

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

要完全的避免冲突,导致误判是行不通的,布隆过滤器是要降低误判

在这里插入图片描述

通过多个哈希函数进行映射,这样如一个冲突没有关系,要三个位置都冲突才是真正的冲突,这样能降低冲突,减少误判。

1.2.代码实现

代码实现

关于字符串哈希算法:博客链接

关于布隆过滤器删除的问题

一般而言布隆过滤器不支持删除,可以定期的更新布隆过滤器。当然也有布隆过滤器是支持删除的。博客链接

关于查找时,在和不在的问题

什么意思呢,当一个位置为0说明还没有字符串,说明该字符一定不在(该位置都为空了,那肯定是没有)!当一个位置为1说明还有字符串,说明字符串是可能存放!这样我们在判断字符串在或不在的时候一旦发现一个位置上有0(添加的时候我们通过哈希计算将其位置设置成1,查找的时候也是通过相同的哈希计算找到相同的位置),肯定该字符串不存在。

完整实现代码

#pragma once
#include<iostream>
#include<bitset>
namespace xiYan
{
    struct BKDRHash
    {
        size_t operator()(const std::string& str)
        {
            size_t hash = 0;
            for (auto ch : str)
            {
                hash = hash * 131 + ch;
            }
            return hash;
        }
    };
    struct APHash
    {
        size_t operator()(const std::string& str)
        {
            size_t hash = 0;
            for (size_t i = 0; i < str.size(); i++)
            {
                size_t ch = str[i];
                if ((i & 1) == 0)
                {
                    hash ^= ((hash << 7) ^ ch ^ (hash >> 3));
                }
                else
                {
                    hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));
                }
            }
            return hash;
        }
    };
    struct DJBHash
    {
        size_t operator()(const std::string& str)
        {
            size_t hash = 5381;
            for (auto ch : str)
            {
                hash += (hash << 5) + ch;
            }
            return hash;
        }
    };
    template<
        size_t N,
        class K = std::string,
        class Hash1 = BKDRHash,
        class Hash2 = APHash,
        class Hash3 = DJBHash
    >
    class BlommFilter
    {
    public:
        void set(const K& key)
        {
            size_t hash1 = Hash1()(key) % N;
            _bs.set(hash1);

            size_t hash2 = Hash2()(key) % N;
            _bs.set(hash2);

            size_t hash3 = Hash3()(key) % N;
            _bs.set(hash3);
        }
        bool test(const K& key)
        {
            size_t hash1 = Hash1()(key) % N;
            if (_bs.test(hash1) == false) return false;
            
            size_t hash2 = Hash2()(key) % N;
            if (_bs.test(hash2) == false) return false;

            size_t hash3 = Hash3()(key) % N;
            if (_bs.test(hash3) == false) return false;

            return true;
        }
    private:
        std::bitset<N> _bs;
    };  
}
1.3.测试代码分析误判率

布隆过滤器应该开多大空间,哈希函数应该用多少个

参考博客链接

误判率和哈希函数个数、布隆过滤器长度、n 为插入的元素个数关系

在这里插入图片描述

k 为哈希函数个数,m 为布隆过滤器长度,n 为插入的元素个数,p 为误判率

关于布隆过滤器应该开多大空间,哈希函数应该用多少个的计算公式:

在这里插入图片描述

通过下面的测试可以看出,当布隆过滤器开辟的空间,越大误判率就越小,哈希个数越多也会降低误判率。

void TestBloomFilter()
{
	srand(time(0));
	const size_t N = 100000;
	xiYan::BloomFilter<N * 8> bf;

	std::vector<std::string> v1;
	std::string url = "如花";

	for (size_t i = 0; i < N; ++i)
	{
		v1.push_back(url + std::to_string(i));
	}

	for (auto& str : v1)
	{
		bf.set(str);
	}

	// v2跟v1是相似字符串集(前缀一样),
	std::vector<std::string> v2;
	for (size_t i = 0; i < N; ++i)
	{
		std::string urlstr = url;
		urlstr += std::to_string(9999999 + i);
		v2.push_back(urlstr);
	}

	size_t n2 = 0;
	for (auto& str : v2)
	{
		if (bf.test(str)) // 误判
		{
			++n2;
		}
	}
	cout << "相似字符串误判率:" << (double)n2 / (double)N << endl;

	// 不相似字符串集
	std::vector<std::string> v3;
	for (size_t i = 0; i < N; ++i)
	{
		string url = "select * from student";
		url += std::to_string(i + rand());
		v3.push_back(url);
	}

	size_t n3 = 0;
	for (auto& str : v3)
	{
		if (bf.test(str))
		{
			++n3;
		}
	}
	cout << "不相似字符串误判率:" << (double)n3 / (double)N << endl;
}
1.4.布隆过滤器的优点
  1. 布隆过滤器可以降低服务器的负载,比如:注册游戏时判断用户名时候存在,就可以套一层布隆过滤器。如果用户名不存在,布隆过滤器可以肯定地判断不存在。如果用户名存在,为了精确地查找再去查找数据库。这减少服务器地IO查询。

    在这里插入图片描述

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

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

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

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

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

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

1.5.关于几道面试题

如何扩展BloomFilter使得它支持删除元素的操作

多标记一个值用于,计数删除。

给两个文件,分别有100亿个query(数据库的查询SQL),我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法

近似算法:将文件A和文件B数据分别存放在两个过滤器中(有过滤的功能),通过两个过滤器求交集。和位图求交集的思路相似。

精确算法:

通过哈希切割(i = Hash(query) % 1000(这里假设切成1000份)),分别对文件A和文件B切分到不同的文件。通过哈希切割相同和冲突的数据会对应下标的文件下。由于哈希切割不是等分切割,如果有大量重复或冲突的的数据,会落入到相同的下标的文件中导致小文件也是过大的。就会有两种情况,经过切分后一个文件有5G有两种情况;情况1.假设有4G是相同的1G是冲突的,情况2.大部分冲突的

解决方法:

把切分的i下标的query读取到一个set中,如果set的inset抛异常(bad_alloc),说明数据大部分是冲突的,更换哈希函数,经行二次切分。如果没有抛异常,说明数据中有大量相同的query那么set是去重的自然就能inset,成功操作。

在这里插入图片描述

然后A小文件和B小文件对应求交集,然后合并。

给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址

就行哈希切割,相同的和冲突的IP都落入对应的下标文件中,然后使用map统计次数,在对每个小文件中最多的进行比较。

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

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

相关文章

深入浅出JVM(一)之Hotspot虚拟机中的对象

本篇文章思维导图 对象的创建 对象的创建可以分为五个步骤:检查类加载,分配内存,初始化零值,设置对象头,执行实例构造器 类加载检查 HotSpot虚拟机遇到一条new指令,会先检查能否在常量池中定位到这个类的符号引用,检查这个类是否类加载过 没有类加载过就去类加载类加载过就进…

中国 AI 开课速度直逼美国 AI 颠覆性创新速度

原文链接&#xff1a; 中国 AI 开课速度直逼美国 AI 颠覆性创新速度 今日热帖&#xff0c;有网友发帖称&#xff1a;Sora 和 ChatGPT 告诉我们&#xff0c;美国确实是遥遥领先&#xff0c;而且还越拉越远。 是不是遥遥领先暂且不说&#xff0c;但领先我们的确是事实。 主要是…

多任务互斥及队列

一.互斥的引入 在FreeRTOS中&#xff0c;互斥&#xff08;Mutex&#xff09;是一种用于保护共享资源的机制。互斥锁可以确保同一时间只有一个任务能够访问共享资源&#xff0c;从而避免了竞态条件和数据不一致的问题。 FreeRTOS中互斥的引入方法&#xff1a; 创建互斥锁&#…

【笔记】【算法设计与分析 - 北航童咏昕教授】绪论

算法设计与分析 - 北航童咏昕教授 文章目录 算法的定义定义性质 算法的表示自然语言编程语言伪代码 算法的分析算法分析的原则渐近分析 算法的定义 定义 给定计算问题&#xff0c;算法是一系列良定义的计算步骤&#xff0c;逐一执行计算步骤即可得预期的输出。 性质 有穷性确…

【Linux】git操作 - gitee

1.使用 git 命令行 安装 git yum install git 2.使用gitee 注册账户 工作台 - Gitee.com 进入gitee&#xff0c;根据提示注册并登录 新建仓库 仓库名称仓库简介初始换仓库 3.Linux-git操作 进入仓库&#xff0c;选择“克隆/下载” 复制下面的两行命令进行git配置 然后将仓库clo…

c语言经典测试题2

1.题1 我们来思考一下它的结果是什么&#xff1f; 我们来分析一下&#xff1a;\\是转义为字符\&#xff0c;\123表示的是一个八进制&#xff0c;算一个字符&#xff0c;\t算一个字符&#xff0c;加上\0&#xff0c;应该有13个&#xff0c;但是strlen只计算\0前的字符个数。所以…

快速学习springsecurity最新版 (版本6.2)---用户认证

简介 ​ Spring Security 是 Spring 家族中的一个安全管理框架。目前比较主流的是另外一个安全框架Shiro&#xff0c;它提供了更丰富的功能&#xff0c;社区资源也比Shiro丰富,但是shiro并不简便,这里轻量级安全框架更推荐国产安全框架satokensatoken官网 ​ 一般大型的项目都…

QT应用软件【协议篇】周立功CAN接口卡代码示例

文章目录 USBCAN系列CAN接口卡规格参数资料下载QT引用周立功的库安装sdk代码USBCAN系列CAN接口卡 USBCAN系列CAN接口卡兼容USB2.0全速规范,可支持1/2/4/8路CAN接口。采用该接口卡,PC机可通过USB连入CAN网络,进行CAN总线数据采集和处理,主要具备以下几大优势特点: 支持车载…

Matlab图像处理——图像编码解码

1.霍夫曼编码和解码 clear clc Iimread(lena.bmp); Iim2double(I)*255; [height,width]size(I); %求图像的大小 HWmatrixzeros(height,width); Matzeros(height,width); %建立大小与原图像大小相同的矩阵HWmatrix和Mat&#xff0c;矩阵元素为0。 HWmatrix(1,1)I(1,1); …

清洁力强的洗地机什么牌子最好?深度清洁的洗地机推荐

在相信很多人在做家务时&#xff0c;或许都会遇到一个尴尬的境地&#xff1a;虽然使用吸尘器清理了地面上的尘土和杂物&#xff0c;然后再使用拖把擦洗地板&#xff0c;但往往还是无法达到十分干净的效果。扫地机器人对于着色严重的垃圾&#xff0c;往往会出现越拖越脏的情况。…

Vue3之生命周期基础介绍

让我为大家介绍一下vue3的生命周期吧&#xff01; 创建阶段&#xff1a;setup 我们直接console.log就可以了 console.log("创建");挂载阶段&#xff1a;onBeforeMount(挂载前)、onMounted(挂载完毕) import { onBeforeMount, onMounted } from vue; // 挂载前 on…

【前端】Vue-Cli 快速创建Vue3项目及一些项目初始化相关

文章目录 前言1. 安装1.1 安装 Vue 脚手架1.2 创建项目1.3 本地运行项目 2. 推送到仓库2.1 远程仓库准备2.2 关于gitIgnore文件2.3 通过git推送至远程仓库 3. 补充与总结3.1 npm 版本是否要升级到最新&#xff1f;3.2 这个项目建议的各种版本3.3 一般前端gitIgnore文件3.4 推荐…

蚂蚁集团开始招聘华为鸿蒙应用研发工程师

早在2023年12月7日支付宝宣布将全面启动鸿蒙原生应用开发。华为表示&#xff0c;支付宝将基于HarmonyOS NEXT版本开发应用&#xff0c;给消费者带来全场景的新体验。头部应用伙伴的加入&#xff0c;大力推动了鸿蒙生态进一步完善。 就近期蚂蚁集团开始招聘华为鸿蒙应用研发工程…

【2024软件测试面试必会技能】Jmeter+ant+jenkins实现持续集成

jmeterantjenkins持续集成 一、下载并配置jmeter 首先下载jmeter工具&#xff0c;并配置好环境变量&#xff1b;参考&#xff1a;https://www.cnblogs.com/YouJeffrey/p/16029894.html jmeter默认保存的是.jtl格式的文件&#xff0c;要设置一下bin/jmeter.properties,文件内容…

成为高级性能测试:发现性能瓶颈掌握性能调优

当下云计算、大数据盛行的背景下&#xff0c;大并发和大吞吐量的需求已经是摆在企业面前的问题了&#xff0c;其中网络的性能要求尤为关键&#xff0c;除了软件本身需要考虑到性能方面的要求&#xff0c;一些硬件上面的优化也是必不可少的。 作为一名测试工作者&#xff0c;对…

SICTF Round#3 の WP

Misc 签到 SICTF{1f4ce05a-0fed-42dc-9510-6e76dff8ff53} Crypto [签到]Vigenere 附件内容&#xff1a; Gn taj xirly gf Fxgjuakd, oe igywnd mt tegbs mnrxxlrivywd sngearbsw wakksre. Bs kpimj gf tank, it bx gur bslenmngn th jfdetagur mt ceei yze Ugnled Lystel t…

书生·浦语大模型实战营-第六课笔记

1.评测追魂夺命三连问 2.主流大拿有话说-评测框架 3.友商最棒儿子最亲&#xff0c;好瓜都是王婆的 4.真枪实弹上战场 为了给平台省点电&#xff0c;我用了自家的电和自家的电脑进行评测。评测的模型也是之前在自己电脑上跑了3轮花费30多个小时的第四课作业微调的法律大模型。s…

智能测径仪 针对设备自身抖动都做了哪些创新加强设计

关键字:测径仪外壳设计,测径仪内部结构,外壳刚性振动,产线共振现象,镜头纯手工擦拭清洗,测径仪智能防抖算法,测径仪多重防抖技术,测径仪防抖技术,测径仪自身防抖&#xff0c; 在生产过程中&#xff0c;被测物不可避免的会发生抖动&#xff0c;测径仪本身也会产生抖动,只是抖动幅…

数据库专题——分库分表

一. 分库分表介绍二. 分库分表实践 一. 分库分表介绍 1.1 分库分表解决了什么问题 先说分库&#xff1a; 《高性能MySQL》中提到了两种数据库扩展方式&#xff1a;垂直扩展和水平扩展。前者意味着买更多性能强悍的硬件&#xff0c;但是总会达到扩展的天花板&#xff0c;且成本…

数字信号处理:傅里叶分析

本文主要参考视频如下&#xff1a; 数字信号处理9-1_线性时不变系统对复指数信号的响应_哔哩哔哩_bilibili 傅里叶分析的主要研究内容如下所示&#xff1a; 注意&#xff0c;计算机中使用的离散傅里叶变换并不是离散时间傅里叶变换&#xff1b; 前四种都是理论上的变换方式&…