哈希表——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,一经查实,立即删除!

相关文章

C++容器

vector 基本特点&#xff1a; 1.内存连续&#xff0c;方便访问 2.动态内存&#xff0c;在数据满时&#xff0c;会自动进行扩容&#xff0c;避免越界访问 3.可以进行插入和删除&#xff0c;效率跟操作位置有关&#xff0c;尾的效率最高#include <iostream> #include <…

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/ 从…

Vue组件通信讲解[父子组件通信]

Vue组件通信讲解 在Vue中&#xff0c;父子组件之间的通信可以通过props和emit来实现。props用于从父组件向子组件传递数据&#xff0c;而$emit用于从子组件向父组件触发事件。 以下是一个包含子传父和父传子通信的Vue案例解决方案&#xff1a; 父组件&#xff1a;Parent.vue…

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;对象也实现了上下文管理器协议。 实现…

【数据结构与算法】二叉树前序,中序,后序遍历非递归版。Leetcode接口

144. 二叉树的前序遍历 - 力扣&#xff08;LeetCode&#xff09; 如果根节点为空&#xff0c;直接返回。初始化一个辅助栈 s&#xff0c;并将根节点入栈。重复以下步骤&#xff0c;直到栈为空&#xff1a; 检查当前节点 tmp&#xff1a; 如果 tmp 不为空&#xff1a; 将当前节…

寒假作业-day2

进程间通信的7种方式&#xff0c;总结出他们的优点 1. 内核提供的原始通信方式有三种 1.1 无名管道 1.2 有名管道 1.3 信号 2. System V提供了三种通信方式 2.1 消息队列 2.2 共享内存 3.1 信号量&#xff08;信号灯集&#xff09; 3. 套接字通信&#xff1a;socket …

十一、计算机分类

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…

前端学习02

1.CSS案例 1.1 内容回顾 1.1.1 搭建骨架 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>body{margin: 0;}.sub-header{height: 100px;background-color: #b0b0b0…

js中常用数组去重方法

js中常用去重方法 一、使用 Set ES6 提供了 Set 类型&#xff0c;它可以自动去重 const arr [1, 2, 2, 3, 3, 4]; const newArr Array.from(new Set(arr)); console.log(newArr ); // [1, 2, 3, 4]二、使用 filter 方法 const arr [1, 2, 2, 3, 3, 4]; const newArr ar…