位图,布隆过滤器,哈希分割

news2024/11/29 10:35:56

文章目录

  • 🚀位图
    • 💡概念
    • 💡接口操作
  • 🚀布隆过滤器
    • 💡思想
    • 💡实现代码
    • 💡实际应用
  • 🚀哈希分割

🚀位图

学习位图前,我们先来看一道题
在这里插入图片描述

  • 用哈希表存储每个整数?不行,数量太大了,存储不下这么多数据。
  • 对这些整数先排序,在用二分查找?也不行,同理,数据量太大了,不好存储数据,排序都能成问题,更何况来查找。
  • 遍历一遍。当然这个是可以的,但是题目是快速,所以时间还是慢了。

好的,这里就慢慢引出今天的主角,位图。

💡概念

位图是一种数据结构,用于表示一个二进制数组中的位或标记


位图通常是一个非常紧凑的数据结构,可以通过一个位来表示一个存储单元。例如,如果一个位图有8个位,那么可以用一个字节表示它们,如果有32个位,那么可以用一个4字节的数据表示它们。


位图的特点是可以高效地进行位运算,例如按位与、按位或、按位取反、按位移动等。因为这些运算都只需要单个 CPU 周期,所以位图非常适合于高性能计算和大型数据集合的处理。

💡接口操作

C++中是有位图的库,我们只需要包头文件 #include< bitset > 即可使用在这里插入图片描述

这里先简单认识一下常用的bitset的接口函数
在这里插入图片描述

set(n) -------- 将第n个比特位设置为1
reset(n) ----- 将第n个比特位设置为0
test(n) ------- 检查第n个比特位,是1返回真,0返回假

那么我们回到题目
用位图来存储每个数字的状态,0表示不在,1表示在,每个比特位表示一个数字,就是有40亿个数(约等于232bit ≈ 4GB大小)也可以装得下,而且查找的时间复杂度是O(1),快的起飞。

🚀布隆过滤器

💡思想

我们知道哈希表是调用一次哈希函数映射到表里的,而布隆过滤器也是这个思想,只不过是多次进行哈希映射,且映射到位图里
在这里插入图片描述
在这里插入图片描述
图片转载

  • 假设 jingdong 映射的是 1 2 3上的比特位,我们在查询的时候发现2号为0,这时候我们可以肯定 jingdong 这个值一定不存在,而我们查询baidu,发现 1 4 7上的比特位都为1,这个时候我们能认为baidu就一定存在吗?答案是否定的,只是可能存在因为不排除其他值的组合恰好凑成了 1 4 7上的比特位为1
  • 布隆过滤器的删除
    布隆过滤器一般是不建议删除的,就算用计数,也会影响到其他值的存在,因为删除操作会增加误判率,所以一般是不建议删除的,如果需要可以根据具体使用场景来实现支持删除的布隆过滤器。

💡实现代码

struct BKDRHash
{
	size_t operator()(const string& s)
	{
		// BKDR
		size_t value = 0;
		for (auto ch : s)
		{
			value *= 31;
			value += ch;
		}
		return value;
	}
};
struct APHash
{
	size_t operator()(const string& s)
	{
		size_t hash = 0;
		for (long i = 0; i < s.size(); i++)
		{
			if ((i & 1) == 0)
			{
				hash ^= ((hash << 7) ^ s[i] ^ (hash >> 3));
			}
			else
			{
				hash ^= (~((hash << 11) ^ s[i] ^ (hash >> 5)));
			}
		}
		return hash;
	}
};
struct DJBHash
{
	size_t operator()(const string& s)
	{
		size_t hash = 5381;
		for (auto ch : s)
		{
			hash += (hash << 5) + ch;
		}
		return hash;
	}
};
struct JSHash
{
	size_t operator()(const string& s)
	{
		size_t hash = 1315423911;
		for (auto ch : s)
		{
			hash ^= ((hash << 5) + ch + (hash >> 2));
		}
		return hash;
	}
};
template<size_t N,
	class K = string,
	class HashFunc1 = BKDRHash,
	class HashFunc2 = APHash,
	class HashFunc3 = DJBHash,
	class HashFunc4 = JSHash>
class bloomfilter
{
private:
	bitset<N> _bs;
public:
	void set(const K& key)
	{
		size_t n1 = HashFunc1()(key) % N;
		size_t n2 = HashFunc2()(key) % N;
		size_t n3 = HashFunc3()(key) % N;
		size_t n4 = HashFunc4()(key) % N;

		_bs.set(n1);
		_bs.set(n2);
		_bs.set(n3);
		_bs.set(n4);
	}
	bool test(const K& key)
	{
		size_t n1 = HashFunc1()(key) % N;
		size_t n2 = HashFunc2()(key) % N;
		size_t n3 = HashFunc3()(key) % N;
		size_t n4 = HashFunc4()(key) % N;

		if (_bs.test(n1) && _bs.test(n2) && _bs.test(n3) && _bs.test(n4))
			return true;
		return false;
	}

	// 一般不实现,因为BloomFilter采用多重哈希映射,就决定了还原的时候必然会影响到其他值
	bool reset(const K& key);
};

💡实际应用

布隆过滤器常用于需要快速判断某个元素是否存在于一个集合中的场景,尤其适用于数据量庞大、查询频繁的情况。以下是一些具体的实际应用:

  1. 网络爬虫优化:网络爬虫需要快速判断一个网页是否已经爬取过,以避免重复爬取。使用布隆过滤器可以快速判断一个网页是否已经爬取过,避免重复爬取。

  2. 垃圾邮件过滤:垃圾邮件过滤需要快速判断一封邮件是否是垃圾邮件。使用布隆过滤器可以将一些常见的垃圾邮件关键词或者特征加入到集合中,用于快速判断待过滤的邮件是否属于垃圾邮件。

  3. 搜索引擎索引优化:在搜索引擎索引过程中,需要快速判断一个单词是否出现在某个网页中。使用布隆过滤器可以将某个单词的哈希值加入到集合中,用于快速判断该单词是否出现在某个网页中。

  4. 大规模缓存数据的快速查询:在缓存数据中,如果需要快速判断某个键是否存在于缓存中,可以使用布隆过滤器来实现快速查询。

总的来说,布隆过滤器在需要快速判断某个元素是否在一个集合中时具有广泛的应用价值,特别是在数据量庞大、查询频繁的场景下,其效果更为明显。

🚀哈希分割

牛客上看到一个很有意思的题目和解法
如图:
在这里插入图片描述
题目网址

解法:

  1. 100G的文件,我们可以分为100种小文件进行统计,其中分发是按照哈希函数来划分,这样可以确保统一类型的ip地址在一个小文件里,而不是分散在各个文件中。
  2. 对每个小文件用unordered_map<string,int> map来进行哈希统计,并统计出最大的,然后map.clear()
  3. 重复步骤二100次,就可以找到出现次数最多的ip地址了

如果要找topK,那就定义优先级队列(小根堆),大的就进队,这样就能拿到topK个了

原理就是:用哈希函数来对数据进行划分范围,做到具有相同属性的值在同一区域内

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

github在线编程

github在线编程 文章目录 github在线编程两种区别演示项目 Ruoyi-VueGitHub Codespaces 演示github 访问项目使用 GitHubCodeSpace 打开该项目查看运行环境安装运行环境初始化myql数据安装 redis运行前端运行后端前后端运行成功测试安装相关插件 GitPod 演示 说明: 目前总结 gi…

路径规划算法:基于果蝇优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于果蝇优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于果蝇优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法果蝇…

聚类算法学习笔记(一)

聚类算法学习笔记&#xff08;一&#xff09; 方法Euclidean Cluster [ 1 ] ^{[1]} [1]SuperVoxel [ 1 ] ^{[1]} [1]Depth Cluster [ 1 ] ^{[1]} [1]SLR: Scan-line Run [ 1 ] ^{[1]} [1]Range Image-based [ 2 ] ^{[2]} [2] 实验对比其他概念Cluster ToleranceKD-Tree Referce…

95后阿里P7晒出工资单:狠补了这个,真香....

最近一哥们跟我聊天装逼&#xff0c;说他最近从阿里跳槽了&#xff0c;我问他跳出来拿了多少&#xff1f;哥们表示很得意&#xff0c;说跳槽到新公司一个月后发了工资&#xff0c;月入5万多&#xff0c;表示很满足&#xff01;这样的高薪资着实让人羡慕&#xff0c;我猜这是税后…

Oracle Linux 9.2 发布 - Oracle 提供支持 RHEL 兼容发行版

Oracle Linux 9.2 发布 - Oracle 提供支持 RHEL 兼容发行版 Oracle Linux with Unbreakable Enterprise Kernel (UEK) & Red Hat compatible kernel (RHCK) 请访问原文链接&#xff1a;https://sysin.org/blog/oracle-linux-9/&#xff0c;查看最新版。原创作品&#xff…

数学建模的初阶-快速上手

目录 第一步&#xff1a;明确问题 第二步&#xff1a;选择建模方法 第三步&#xff1a;收集数据 第四步&#xff1a;构建数学模型 第五步&#xff1a;模型验证与评估 数学建模软件推荐 统计模型 (1) 线性回归模型 (2) 逻辑回归模型 (3) 时间序列模型 优化模型 (1) …

cuda编程学习——运行错误检测(四)

前言 参考资料&#xff1a; 高升博客 《CUDA C编程权威指南》 以及 CUDA官方文档 CUDA编程&#xff1a;基础与实践 樊哲勇 文章、讲解视频同步更新公众《AI知识物语》&#xff0c;B站&#xff1a;出门吃三碗饭 1:编写头文件erro.cuh 编写一个头文件&#xff08;error.cuh&…

LabVIEWCompactRIO 开发指南第六章38

LabVIEWCompactRIO 开发指南第六章38 了解数据如何在模块硬件组件和LabVIEW FPGA框图之间传输&#xff0c;可以帮助开发更好的程序并更快地进行调试。本节介绍不同的硬件体系结构&#xff0c;模拟和数字C系列I/O模块以及如何与每个模块通信。这些模块通常用于测量或控制信号&a…

10. python字典

文章目录 一、什么是字典二、访问键-值对三、添加、修改键-值对四、删除键-值对4.1 语句del4.2 方法pop() 五、创建空字典六、遍历字典6.1方法items()6.2方法keys()6.3方法values() 七、嵌套7.1 字典列表7.2 在字典中存储列表7.3 在字典中存储字典 一、什么是字典 #创建一个字…

canal server 标准化集群搭建(一)

1.背景 随这业务增加&#xff0c;数据同步服务 canal server 需求与日俱增&#xff0c;以往私搭乱建的 canal server 不符合运维标准化。 2.目的 规范 canal server 的部署&#xff0c;形成固定操作流程及文档 3. 环境版本 canal server&#xff1a; canal.deployer-1.1.…

电装光庭汽车电子(武汉)有限公司

电装光庭汽车电子&#xff08;武汉&#xff09;有限公司 &#xff08;汽车座舱显示系统&#xff0c;汽车电子产品及其材料和组件的开发&#xff0c;设计&#xff0c;制造&#xff0c;销售&#xff0c;批发&#xff0c;进出口&#xff09; 一、公司介绍 电装光庭汽车电子是一…

Android中使用kotlin进行xutils数据库版本升级

Android中使用kotlin进行xutils数据库版本升级 前言 最近的项目是一个很老的项目&#xff0c;数据库采用的是xutils中的数据库&#xff0c;之前的业务没有关于版本变更和数据库修改的业务&#xff0c;这次新需求数据库需要新加一张表&#xff0c;之前的表也需要修改字段&…

2022机器学习阶段性复盘

2022机器学习阶段性复盘 文章目录 2022机器学习阶段性复盘一、业务洞察1.1 业务调研1.2 采样策略 一、特征工程1.1 特征筛选之iv_psi1.2 特征筛选之启发式搜索1.3 时间特征的曲率变换1.4 多重共线性特征的剔除1.5 什么样的特征适合树模型或LR模型1.5 什么样的特征是稳定可泛化特…

cuda编程学习——GPU加速/时间计时Clock 干货向(五)

前言 参考资料&#xff1a; 高升博客 《CUDA C编程权威指南》 以及 CUDA官方文档 CUDA编程&#xff1a;基础与实践 樊哲勇 文章所有代码可在我的GitHub获得&#xff0c;后续会慢慢更新 文章、讲解视频同步更新公众《AI知识物语》&#xff0c;B站&#xff1a;出门吃三碗饭 …

路径规划算法:基于花授粉优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于花授粉优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于花授粉优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法…

面试官:这么简单的二叉树算法都不会?

今天我们来看一个有趣的算法题&#xff0c;也是一道高频面试题。这个题目是leetcode的第572题&#xff0c;要求是这样的&#xff1a;给定两颗二叉树A和B&#xff0c;判断B是否是A的子树。在下面这个例子中可以看到B是A的子树。 想一想该怎样解决这个问题呢&#xff1f;如果B是A…

Python丨tkinter开发常用的29种功能用法(建议码住)

在Python软件开发中&#xff0c;tkinter中command功能的作用是为按钮、菜单等组件绑定回调函数&#xff0c;用户操作该组件时会触发相应的函数执行。 本文涵盖了各种组件和功能&#xff1a; 1、为Button组件&#xff08;按钮&#xff09;绑定回调函数 import tkinter as tk …

模拟量偏差报警功能块(SCL代码)

工业模拟量采集的相关基础知识,可以查看专栏的系列文章,这里不再赘述,常用链接如下: PLC模拟量采集算法数学基础(线性传感器)_plc傳感器數據轉化_RXXW_Dor的博客-CSDN博客模拟量采集库如何设计,具体算法代码请参看我的另一篇博文:PLC模拟量输入 模拟量转换FC:S_ITR_R…

栈和队列(详解)

&#x1f355;博客主页&#xff1a;️自信不孤单 &#x1f36c;文章专栏&#xff1a;数据结构与算法 &#x1f35a;代码仓库&#xff1a;破浪晓梦 &#x1f36d;欢迎关注&#xff1a;欢迎大家点赞收藏关注 文章目录 &#x1f353;栈1. 栈的概念及结构2. 栈的实现2.1 初始化栈2.…

MySQL运维篇(三)

五.读写分离 5.1 介绍 读写分离,简单地说是把对数据库的读和写操作分开,以对应不同的数据库服务器。主数据库提供写操作&#xff0c;从数据库提供读操作&#xff0c;这样能有效地减轻单台数据库的压力。 通过MyCat即可轻易实现上述功能&#xff0c;不仅可以支持MySQL&#x…