哈希表——C++

目录

一、首先使用拉链法:

 二、开放寻址法

三、字符串哈希

1.具体如何使用进制的方式来存储字符前缀的可以看这个y总的这个图

2.接下来说一说算某个中间的区间的字符串哈希值


哈希表是一种数组之间互相映射的数据结构,比如举个简单的例子一个十个的数组要用一个五个的数组表示,我们可以使用取模的方法将十个数组中的数组映射到五个数字的小数组中。

核心思想是将数据项的键值(Key)通过哈希函数转换成数组的索引,从而直接访问数组中的位置来存储或查找数据项。

但是一个大的数组映射到小的数组中是很难避免映射冲突的问题的,为了解决这类问题,我们常用两个方法来解决;

  • 拉链法
  • 开放寻址法

一、首先使用拉链法:

拉链法顾名思义就是一个数组,每个数组上链接一个单链表,形状类似拉链,故拉链。

 但是如何取模运算,是我们需要解决的问题。

听y总说寻找大于规定范围最小的质数是冲突最小(我不知道为撒,但是听说数学有证明)

#include<iostream>
#include<cstring>
using namespace std;int main()
{for(int i=1e5;;i++){bool flag=true;for(int j = 2 ; j * j <=i;j++){if(i % j == 0){flag=false;break;}}if(flag){cout<<i<<endl;break;}}return 0;
}

例题:https://www.acwing.com/activity/content/problem/content/890/

#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+3;
int h[N],e[N],ne[N],idx;void insert(int x)
{int k=(x%N+N)%N;  //保证k的值不为负数e[idx]=x;ne[idx]=h[k];h[k]=idx;idx++;
}bool find(int x)
{int k=(x%N+N)%N;  //保证k的值不为负数for(int i=h[k];i!=-1;i=ne[i]){if(e[i]==x)  return true;}return false;
}int main()
{int m;cin>>m;memset(h,-1,sizeof (h));while(m--){char op[2];int x;scanf("%s%d",op,&x);if(*op=='I'){insert(x);}else{if(find(x)) puts("Yes");elseputs("No");}}return 0;
}

 二、开放寻址法

开放寻址法可以叫它为蹲坑法,通常N要是数据范围的两倍,然后找最小的大于数据范围的质数

然后在相应的地方进行插入数据。

#include<iostream>
#include<cstring>
using namespace std;const int N=200003,null=0x3f3f3f3f;
int h[N];int find(int x)
{int k=(x % N + N) % N;while(h[k]!=null && h[k]!=x){k++;//到头就从头再来if(k==N) k=0;}return k;//保证k要么是空位置的地址,要么是这个数已经被存放过了
}int main()
{int n;scanf("%d",&n);memset(h,0x3f,sizeof h);while(n--){char op[2];int x;scanf("%s%d",op,&x);if(*op == 'I'){h[find(x)] = x;}else{if(h[find(x)] == null) puts("No");else puts("Yes");}}return 0;
}

三、字符串哈希

一般常使用哈希来解决字符串的问题,常用的方法就是将一个字符串差分成字符前缀,然后存储每个字符前缀的哈希值,然后这个哈希值常使用一种进制的表示方式来确定,然后在进行取余。(要点:一般使用131进制,取余的除数是2^{^{^{64}}},而且使用unsigned long long 来存储也就可以通过溢出直接进行自动取余)。

1.具体如何使用进制的方式来存储字符前缀的可以看这个y总的这个图

需要注意的是这里的哈希值的处理方式我们需要认为是不存在冲突的,这一点和之前的数值哈希有所不同,而且还要注意的是在映射的时候是不可以映射成为0的。

举个例子解释一下

如何某个字符前缀会映射成为0,那比如说A是0,那AB也就是0了,这样是不符合要求的。

2.接下来说一说算某个中间的区间的字符串哈希值

如图所示,最重要的公式就是h[R]-h[l-1]*p^{r-l+1}

举个例子方便理解

我们在预处理h[i] 数组的时候,是把左边看成高位,右边看成低位(这与我们的习惯是相同的)
下面给出例子,计算[4,5]之间"de" 的哈希值   高位   a       b   c   d    e  低位  
                                                                               a        b      c  
                                             这是数组的下标        1      2   3    L    R   
                                       这里是P进制下位权    (p^4)  p^3  p^2   p^1   1

   我们在前缀和那节课已经学过了,怎么计算区间的部分和.  h[R] - h[L - 1].
   仔细一看,不对劲,位置对不上. 因此我们将字符串 "左移",为他们补上位权,这样子就能做到一一对应
                                    高位    a       b   c   d    e  低位  
                                                 a      b   c   '\0' '\0'
                 这是数组的下标        1      2   3    L    R   
         这里是P进制下位权    (p^4)  p^3  p^2   p^1   1

    为了方便理解,我用"\0"表示无意义字符. 这个时候就能计算了对吧?
    那位移是多少呢?
    就是 R - L + 1,在本例中, 5 - 3 + 1 = 2,左移两位. 补齐低位.

例题:https://www.acwing.com/activity/content/problem/content/891/

#include<iostream>
using namespace std;const int N=1e5+10,jinzhi=131;unsigned long long h[N],p[N];//h是存放每个字符子串的哈希值,p是存放字符串的权重的
char str[N];int get(int l,int r)
{return h[r]-h[l-1]*p[r-l+1];
}int main()
{int n,m;scanf("%d%d",&n,&m);scanf("%s",str+1);//初始化p[0]=1;for(int i=1;i<=n;i++){h[i]=h[i-1]*jinzhi+str[i];p[i]=p[i-1]*jinzhi;}while(m--){int l1,l2,r1,r2;scanf("%d%d%d%d",&l1,&r1,&l2,&r2);if(get(l1,r1)==get(l2,r2)){puts("Yes");}else puts("No");}return 0;
}

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

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

相关文章

ArrayList常见问题

ArrayList 1、ArrayList底层的实现原理是什么 2、ArrayList list new ArrayList(10)中的list扩容几次 3、如何实现数组和list之间的转换 4、ArrayList和LinkedList的区别是什么

办公软件巨头CCED、WPS面临新考验,新款办公软件异军突起

办公软件巨头CCED、WPS的成长经历 众所周知&#xff0c;CCED和WPS在中国办公软件领域树立了两大知名品牌的地位。然而&#xff0c;它们的成功并非一朝一夕的成就&#xff0c;而是历经了长时间的发展与积淀。 在上世纪80年代末至90年代初&#xff0c;CCED作为中国大陆早期的一款…

java大学生科研创新项目在线管理系统 springboot+vue

预期成果&#xff1a; &#xff08;1&#xff09;实现一个完整的大学生科创项目在线管理系统的设计与实现&#xff0c;可以运行演示。 &#xff08;2&#xff09;预计本系统的页面完整&#xff0c;页面所有文字和图片无漏字、错字、重叠不显示的现象&#xff0c;页面所有链接和…

Unity Meta Quest MR 开发(三):Scene API 配置+实现虚拟与现实之间的碰撞

文章目录 &#x1f4d5;教程说明&#x1f4d5; Scene 配置⭐开启场景理解功能和应用访问空间数据的权限⭐OVRSceneManager⭐制作 Plane Prefab 和 Volume Prefab⭐运行场景⭐添加透视材质 &#x1f4d5;虚拟与现实物体的碰撞&#xff08;弹球 Demo&#xff09;&#x1f4d5;Mes…

web前端--------渐变和过渡

线性渐变&#xff0c;是指颜色沿一条直线进行渐变&#xff0c;例如从上到下、从左到右。 当然&#xff0c;CSS中也支持使用角度来设置渐变的方向&#xff0c;角度单位为deg。 0deg&#xff0c;为12点钟方向&#xff0c;表示从下到上渐变。 90deg&#xff0c;为3点钟方向&…

Android13源码下载及全编译流程

目录 一、源码下载 1.1、配置要求 1.1.1、硬件配置要求 1.1.2、软件要求 1.2、下载环境搭建 1.2.1、依赖安装 1.2.2、工具安装 1.2.3、git配置 1.2.4、repo配置 1.3、源码下载 1.3.1、明确下载版本 1.3.2、替换为清华源 1.3.3、初始化仓库并指定分支 1.3.4、同步全部源码 二、…

【24美赛思路已出】2024年美赛A~F题解题思路已出 | 无偿自提

A题&#xff1a;资源可用性和性别比例 问题一&#xff1a; 涉及当灯鱼种群的性别比例发生变化时&#xff0c;对更大的生态系统产生的影响。为了分析这个问题&#xff0c;可以采用以下的数学建模思路&#xff1a;建立灯鱼种群模型&#xff1a; 首先&#xff0c;建立一个灯鱼种群…

20240203在WIN10下安装Miniconda

20240203在WIN10下安装Miniconda 2024/2/3 21:06 缘起&#xff1a;最近学习stable-diffusion-webui.git&#xff0c;在Ubuntu20.04.6下配置SD成功。 不搞精简版本&#xff1a;Miniconda了。直接上Anacoda&#xff01; https://www.toutiao.com/article/7222852915286016544/ 从…

Qt 的安装以及项目的创建

目录 Qt简介Qt 开发环境安装的过程环境变量的配置Qt SDK 中的重要的工具创建一个 Qt 项目 Qt简介 开始安装教程前&#xff0c;首先来了解一下什么是QT。 QT&#xff08;Quick Thought&#xff09;是一个基于Qt库的快速应用程序开发框架。它提供了一套完整的开发工具和库&…

文本检测学习笔记_CTPN

论文地址&#xff1a;https://arxiv.org/pdf/1609.03605.pdf 开源代码&#xff1a;https://github.com/lvliguoren/pytorch_ctpn?tabreadme-ov-file 本文主要的的内容 提出了一种将文本视为由密集排列的具有固定宽度的文本候选区域组成的序列的方法。这些文本候选区域可以通…

国际国内 IT行业有哪些证书含金量高?

一、前言 在信息技术飞速发展的今天&#xff0c;IT行业证书作为衡量专业技能和知识水平的重要标准&#xff0c;越来越受到业界的重视。对于IT从业者而言&#xff0c;拥有一些权威性的证书不仅能够证明自己的专业能力&#xff0c;更是职业发展的有力助推器。基于多年的行业经验…

Python中with管理上下文

上下文管理器 上下文管理器本质就是能够支持with操作。 任何实现了 __enter__() 和 __exit__() 方法的对象都可称之为上下文管理器&#xff0c;上下文管理器对象可以使用 with 关键字。显然&#xff0c;文件&#xff08;file&#xff09;对象也实现了上下文管理器协议。 实现…

十一、计算机分类

1、按照性能和用途分类 计算机分类 计算机按照性能、用途和规模可以分为以下几种类型&#xff1a; 1&#xff09;巨型机&#xff08;超级计算机&#xff09; 采用大规模并行处理体系结构。运算速度最快、体积最大、价格最昂贵。主要用于尖端科学研究领域&#xff0c;如灾难预测…

《计算机网络简易速速上手小册》第2章:计算机网络协议和标准(2024 最新版)

文章目录 2.1 IPv4 与 IPv6 - 网络世界的地址簿2.1.1 基础知识2.1.2 重点案例&#xff1a;使用 Python 查询本机 IPv4 和 IPv6 地址2.1.3 拓展案例1&#xff1a;使用 Python 创建简单的 IP 地址转换工具2.1.4 拓展案例2&#xff1a;使用 Python 检测本地网络的 IP 版本支持 2.2…

ES6-对象的解构赋值

一、区别一下数组的解构赋值 - 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的&#xff0c;变量的取值由它的位置决定&#xff1b;而对象的属性没有次序&#xff0c;变量必须与属性同名&#xff0c;才能取到正确的值二、说明 - 对象的解构赋值的内部机制&#…

【Vitis】Vitis HLS学习系列笔记 :第一个例程

在学习vitis的过程中一定要跑几个例程试试看&#xff0c;这中间遇到了几个小问题&#xff0c;记录下 有干货&#xff0c;请注意查收&#xff1a;作为新手&#xff0c;跑例程大概率会遇到问题&#xff0c;这里记录几个问题&#xff0c;如果刚好你也遇到&#xff0c;一定会帮到你…

XML详解

文章目录 XML简介语法约束DTDSchema 解析Jsoup使用对象详解JsoupDocumentElementsElementNode XML 简介 概述&#xff1a;Extensible Markup Language 可扩展标记语言 可扩展&#xff1a;标签都是自定义的。 功能 数据存储&#xff1a;XML 可以用来存储结构化数据&#xff0c…

HSRP配置指南

实验大纲 第 1 部分&#xff1a;验证连通性 步骤 1&#xff1a;追踪从 PC-A 到 Web 服务器的路径 步骤 2&#xff1a;追踪从 PC-B 到 Web 服务器的路径 步骤 3&#xff1a;观察当 R3 不可用时&#xff0c;网络的行为 第 2 部分&#xff1a;配置 HSRP 主用和 备用路由器 步…

rasa3.X 自定义action的注册问题

rasa3.X 自定义action的注册问题 文章目录 rasa3.X 自定义action的注册问题前言一、问题重述二、问题解决 前言 幸好在这之前抽时间稍微看了一点django源码&#xff0c;让我对于python的导入机制有了一个概念。虽然还不是很确切的知道python import机制&#xff0c;不过在看到…

QT学习日记 | 初始QT

目录 一、创建QT文件 二、目录结构讲解 1、.pro文件 2、源文件与头文件 3、编译运行 4、界面文件 三、梦开始的地方&#xff08;Hello World&#xff01;&#xff09; 1、代码方式 2、拖拽方式 四、Qt中的“容器” 五、Qt的对象树机制 1、对象树的引入 2、对象树…