STL容器之哈希的补充——其他哈希问题

1.其他哈希问题

​ 减少了空间的消耗;

1.1位图

​ 位图判断在不在的时间复杂度是O(1),速度特别快;

​ 使用哈希函数直接定址法,1对1映射;

​ 对于海量的数据判断在不在的问题,使用之前的一些结构已经无法满足,空间消耗过于严重,位图则可以较好的解决此问题;

​ 对于bit位的改变除了位运算就是位段;

1.1.2位图结构的实现

​ 小端机与我们看数据的顺序相反,几个数据连续存储从低地址到高地址,低位-高位,低位-高位。

namespace Bitset
{template <size_t N>//无符号整数42亿9千万,需要每个整数用一个bit位来标识在不在,大约500兆class BitSet{public:// 用构造函数开空间BitSet(){a_.resize(N / 32 + 1);}public:// 将x映射的哪个标记映射成为1void set(size_t x){size_t i = x / 32;size_t j = x % 32;a_[i] |= (1 << j); // 小端机,开头就是低位,所以直接左移j位}// 将x映射的哪个标记映射成为0void reset(size_t x){size_t i = x / 32;size_t j = x % 32;a_[i] &= (~(1 << j));}bool test(size_t x){size_t i = x / 32;size_t j = x % 32;return a_[i] & (1 << j);// if (a_[i] & (1 << j))// {//     std::cout << "存在" << std::endl;//     return true;// }// else// {//     std::cout << "不存在" << std::endl;//     return false;// }}private:std::vector<int> a_;};
}
1.1.3库里面对于位图结构的实现

在这里插入图片描述

1.1.4位图的扩展

1.100亿个整数,设计算法找到只出现一次的数,

​ 思路1:使用两个比特位组合,来表示没有出现,出现一次和出现两次及以上;

​ 思路2:使用2个位图,对应位置组合使用;

2.两个文件分别有100亿整数,1g内存找交集;

1.1.5位图的应用

1.快速查找某个数据是否在一个集合中

2.排序 + 去重

3.两个集合的交集、并集等

4.操作系统中磁盘块标记

1.2布隆过滤器

​ 作用:过滤掉确定性的数据,降低数据库的查询负载压力;对于不确定的数据,降低误判率;

​ 使用除留余数法,产生多对一,对于整型可以使用位图来实现,对于字符串是先对应一个整数,但是不可能无限扩容,会存在双重哈希冲突,对于存在可能误判,是不准确的,而对于不存在一定是准确的;

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

​ 使用布隆过滤器可以减少误判率;一个值映射位图的多个位置,如果多个位置都为1,才能说明在;就像是现实生活中,信息越多描述就更准确;

1.2.1应用场景

​ 1.不需要精确的场景,即使用降低误判的特性:比如快速判断昵称是否被使用过,将昵称存放到一个布隆过滤器里面,存在误判,但是可以接受,比如用户知道昵称不可用就会自动用其他昵称,不会产生巨大的问题;

​ 2.需要精确的场景,即使用不存在是准确的特性,昵称不存在快速响应,昵称存在去数据库进行查找,可以起到过滤一部分确定数据的效果;

​ 3.布隆过滤器不仅可以过滤字符串,也可以针对其他类型;

1.2.2布隆过滤器模拟实现

​ 偶数用位运算表示,n&1==0,就是偶数;

​ 使用不同的哈希算法得到不同的整数映射,多对一的映射减少了误判,同时也带来了空间上的消耗空间减少也会增加误判的机率;

一般不允许使用reset,否则会影响很多映射,即多对一使得关联度增加了,一个修改就会影响另一个,可以使用引用计数的方法,同时还需要多开空间存计数,这样就可以保护数据。

namespace Bloomfilter
{struct BKDR{size_t operator()(const std::string &str){size_t i = 0;for (const auto &e : str){i *= 131;i += e;}return i;}};struct AP{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));elsehash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));}return hash;}};struct DJB{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 = BKDR, class Hash2 = AP, class Hash3 = DJB> // 可以使用BKDR算法class BloomFilter{public:void set(const K &key){size_t hash1 = BKDR()(key) % N;bf_.set(hash1);size_t hash2 = AP()(key) % N;bf_.set(hash2);size_t hash3 = DJB()(key) % N;bf_.set(hash3);}bool test(const K &key){size_t hash1 = BKDR()(key) % N;if (bf_.test(hash1) == false){return false;}size_t hash2 = AP()(key) % N;if (bf_.test(hash2) == false){return false;}size_t hash3 = DJB()(key) % N;if (bf_.test(hash3) == false){return false;}return true; // 存在误判}private:// 私有成员std::bitset<N> bf_;};
}
1.2.3哈希函数个数和布隆过滤器长度的选择

在这里插入图片描述

k为哈希函数的个数,m为布隆过滤器的长度,n为插入元素的个数,这样可以使得误判率相对较低;

1.2.4布隆过滤器优缺点

优点:

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

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

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

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

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

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

缺点:

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

2.不能获取元素本身 ;

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

4.如果采用计数方式删除,可能会存在计数回绕问题 ;

8.2.5布隆过滤器的扩展

1.给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出

精确算法和近似算法 ;

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

1.3哈希切割

​ 问题:1.将大文件切割是因为在磁盘中查找太慢,应载入内存查找;2.平均切分要查询的key在每个小文件中都可能存在,都得查找一次;

​ 而是用哈希切割,将大文件进行切割,切割成N份,用哈希算法将查询字符串映射成整数,然后%N,最后得到的映射值i就是被切割的第i个小文件;这样就可以根据编号进行查找,不用遍历所有的小文件;

​ 原理是:存在哈希冲突映射了错误的值,但是正确的值一定在这个位置对应的小文件,使得范围大幅度减少;即过滤很大一批无效数据;

1.3.1哈希切割应用

​ 1.哈希切割解决大文件找交集;

​ 哈希切分后还可能某一个小文件过大;文件过大可能是1.大多数query冲突;2.大多数query相同,部分冲突;

​ 对于小文件过大的解决方法:1.set去重,如果成功说明有大量相同数据,这样文件就小了,如果失败抛异常,则对此文件,使用其他哈希函数进行二次哈希切分,这样文件也小了;

​ 2.最大/topk问题

​ 哈希切割完,用map统计次数,然后用另一个值记录最大的值,清理map遍历其他小文件,更新最大值;

如果是topk就建立一个k个值的小堆,插入k个较大值然后不断更新;

补充:CPU的高速缓存与内存和磁盘间的局部性原理的预加载机制

​ CPU高速缓存是,内存会将一段数据先加载到cache中,CPU会向cache进行读取,存在缓存命中问题;

​ 局部性原理的预加载机制是,内存磁盘读取都是按照一定的大小进行的,这样就可以一次性读到多个数据;

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

13. 用户注册功能实现

文章目录 一 、增加路由二、书写流程控制&#xff08;controller&#xff09;逻辑三、书写业务逻辑四、与DB交互五、测试 代码地址&#xff1a;https://gitee.com/lymgoforIT/bluebell 一 、增加路由 添加路由&#xff0c;使用分组管理 v1 : r.Group("/api/v1")//…

代码随想录训练营第41天 | 动态规划:01背包理论基础、动态规划:01背包理论基础(滚动数组)、LeetCode 416.分割等和子集

动态规划&#xff1a;01背包理论基础 文章讲解&#xff1a;代码随想录(programmercarl.com) 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;_哔哩哔哩_bilibili 动态规划&#xff1a;01背包理论基础&#xff08;滚动数组&#xff09; 文章讲解&#xff1a;代码随想录(…

OpenStack之keystone(用户认证)

Keystone&#xff08;认证&#xff09; Keystone 概述 1)管理用户及其权限 2)维护OpenStack Services 的 Endpoint 3)Authentication&#xff08;认证&#xff09;和 Authorization&#xff08;授权&#xff09; keystone的名词概念 1.User&#xff08;用户或服务&#xf…

L-2:插松枝(Python)

作者 陈越 单位 浙江大学 人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上&#xff0c;做成大大小小的松枝。他们的工作流程&#xff08;并不&#xff09;是这样的&#xff1a; 每人手边有一只小盒子&#xff0c;初始状态为空。每人面前有用不完的松枝干和一个推送…

人工智能|机器学习——DBSCAN聚类算法(密度聚类)

1.算法简介 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法&#xff0c;簇集的划定完全由样本的聚集程度决定。聚集程度不足以构成簇落的那些样本视为噪声点&#xff0c;因此DBSCAN聚类的方式也可以用于异常点的检测。 2.算法原…

ROS2动作通信的实现

文章目录 1.动作通信的概念及应用场景1.1 概念1.2 应用场景 2.准备工作3.动作通信的实现3.1 动作通信接口消息3.2 服务端实现3.3 客户端实现3.4 编译及运行 1.动作通信的概念及应用场景 1.1 概念 动作通信适用于长时间运行的任务。就结构而言动作通信由目标、反馈和结果三部分…

基于springboot+vue实现高校学生党员发展管理系统项目【项目源码+论文说明】

基于springboot实现高校学生党员发展管理系统演示 摘要 随着高校学生规模的不断扩大&#xff0c;高校内的党员统计及发展管理工作面临较大的压力&#xff0c;高校信息化建设的不断优化发展也进一步促进了系统平台的应用&#xff0c;借助系统平台可以实现更加高效便捷的党员信息…

给定时间求这是本年的第几天

之前我在编写个代码的时候是把它用大量的if逻辑判断语句&#xff0c;我并没有把是闰年这个条件选择出来&#xff0c;只是依据一般的想法—— #include <stdio.h> #define M 13 int main() {/********** Begin **********/int days[M] {0,31,28,31,30,31,30,31,31,30,3…

transformer--使用transformer构建语言模型

什么是语言模型? 以一个符合语言规律的序列为输入&#xff0c;模型将利用序列间关系等特征&#xff0c;输出一个在所有词汇上的概率分布.这样的模型称为语言模型. # 语言模型的训练语料一般来自于文章&#xff0c;对应的源文本和目标文本形如: src1"Ican do",tgt1…

抖音短视频素材哪里找,推荐五个好用的抖音素材网站

不知道你有没有想过一个问题&#xff0c;为什么别人都能找到那种高质量的视频素材&#xff0c;画质特别高清&#xff0c;甚至是4K的内容&#xff0c;而你需要视频素材却不知道去哪里找&#xff1f;网上有各种参差不齐的网站&#xff0c;变着法的想掏空你那本不富裕的腰包。今天…

消息队MQ

文章描述 &#xff1a;&#x1f60a; 作者&#xff1a;Lion J &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_69252724 &#x1f389; 主题&#xff1a; 消息队列MQ_rabbitMQ搭建 ⏱️ 创作时间&#xff1a;2024年03月9日 ———————————————…

GIS之深度学习08:安装GPU环境下的pytorch

环境&#xff1a; cuda&#xff1a;12.1.1 cudnn&#xff1a;12.x pytorch&#xff1a;2.2.0 torchvision&#xff1a;0.17.0 Python&#xff1a;3.8 操作系统&#xff1a;win &#xff08;本文安装一半才发现pytorch与cuda未对应&#xff0c;重新安装了cuda后才开始的&a…