7、哈希表

news2024/11/24 20:52:26

7、哈希表

哈希表最主要的作用就是把一个比较庞大的空间或者值域 映射到比较小的值域 (0-n)

就是将-10^9 ~10^9 映射到 0 ~10^5

一、存储结构

映射的方法可以是 h(x) = x mod 10^5

但是这样映射会出现一个问题 可能会有重复的数字出现

所以就引出了两个方法 开放寻址法 和 拉链法

1、开放寻址法

也开一个一维数组 但是一维数组的长度要是题目所给数据的2-3倍

h(x) = k

从第k个数字开始去找 如果已经存在了 就去找下一个

在这里插入图片描述

2、拉链法

开一个一维数组去存储值 比如映射到0~10^5

则开一个长度为10^5的数组

如图所示 当11和23都映射到3这个位置的时候

可以在3的下面开一个拉链 去记录所有映射到这个位置上的数字

在这里插入图片描述

题目:模拟散列表

维护一个集合,支持如下几种操作:

I x,插入一个数 x;
Q x,询问数 x 是否在集合中出现过;
现在要进行 n 次操作,对于每个询问操作输出对应的结果。

输入格式:

第一行包含整数 n,表示操作数量。
接下来 n 行,每行包含一个操作指令,操作指令为I x,Q x中的一种。

输出格式:

对于每个询问指令Q x,输出一个询问结果,如果 x 在集合中出现过,则输出 Yes,否则输出 No。
每个结果占一行。

数据范围:

1≤n≤10^5

-10^9<=x <= 10^9

输入样例:

5
I 1
I 2
I 3
Q 2
Q 5

输出样例:

Yes
No

代码一(拉链法):
#include <iostream>
#include <cstring>
using namespace std;

const int N = 10010;

int h[N];
int e[N], ne[N], idx;

void insert(int x)
{
	//首先先把x映射到数组中去
	int k = (x % N + N) % N;

	e[idx] = k;
	ne[idx] = h[k];
	h[k] = idx++;

}

bool find(int x)
{
	//同理  也是先将其映射到数组中
	int k = (x % N + N) % N;
	for (int i = h[k]; i != -1; i++)
	{
		if (e[i] = k) return true;
	}
	return false;
}

int main()
{
	int n; cin >> n;
	memset(h,-1,sizeof h);
	while (n--)
	{
		char op[2];
		scanf("%s",op);
		if (op[0] == 'I')
		{
			int x; cin >> x;
			insert(x);
		}
		else {
			int x; cin >> x;
			if (find(x)) cout << "Yes";
			else  cout << "No";
		}
	}

	return 0;
}

二、字符串哈希的方式

O(1)

快速判断两个字符串是否相等

就可以用该方法

字符串前缀哈希法

给定一个字符串

在这里插入图片描述

首先预处理所有前缀的哈希值

在这里插入图片描述

(如何来定义每一个前缀的哈希值)

p进制

假设A-Z个字母 求出这个数组的十进制数字

(相加的结果可能过于大 所以mod上一个数字) 、

就可以把整个数字映射到0 - Q-1上

在这里插入图片描述

注意

1、不能够映射成0

如果可以的话 A -> 0 AA-> 0 重复了

2、不存在冲突的情况

p = 131 或者13331

Q = 2^64

这样取值 在一般情况下 可以假定不会出现冲突

怎么求出 L-R这一段的哈希值

在这里插入图片描述

把1-R的所有的数字 看成是p进制的数字 左边是高位 右边是低位

即 在h[R]中 R就是第0位 1就是R-1位

h[L-1] 中 L-1就是第0位 1是L-2位

已知从1-R的哈希值h[R] = p^(r-1) ….p^0

和1-L-1 的哈希值 h[L-1] = p^(l-2) …….p ^0

因此让h[L-1] * p^(R-L+1) =》作用是让h[L]往右移动若干位 与h[R]对齐

*=》h[R] - h[L-1] p^(R-L+1)

思路整理
  • 把字符串看成是一个 P 进制数,每个字符的 ASCII 码对应数的一位
  • ASCII 范围 0 - 127,最少 128 进制,经验上取 131 或 13331 冲突率低
  • 字符串很长,对应的数太大,通过模 2^64 把它映射到 [0, 2^64 - 1]
  • 用 unsigned long long 存储,溢出相当于对 2^64 取模,省略了手动运算
  • 该方法的好处是,可以利用前缀哈希直接求出子串哈希(减去高位)
hash(DEF) = hash(ABCDEF) - hash(ABC) x P^3
    1       2       3       4       5       6
    A       B       C       D       E       F  
  1xP^5 + 2xP^4 + 3xP^3 + 4xP^2 + 5xP^1 + 6xP^0

                            D       E       F
                          4xP^2 + 5xP^1 + 6xP^0

    A       B       C  
  1xP^2 + 2xP^1 + 3xP^0
题目描述 字符串哈希

给定一个长度为 𝑛 的字符串,再给定 𝑚 个询问,每个询问包含四个整数 𝑙1,𝑟1,𝑙2,𝑟2,请你判断[𝑙1,𝑟1] 和[𝑙2,𝑟2] 这两个区间所包含的字符串子串是否完全相同。

字符串中只包含大小写英文字母和数字。

输入格式

第一行包含整数 𝑛 和 𝑚,表示字符串长度和询问次数。

第二行包含一个长度为 𝑛 的字符串,字符串中只包含大小写英文字母和数字。

接下来 𝑚 行,每行包含四个整数 𝑙1,𝑟1,𝑙2,𝑟2,表示一次询问所涉及的两个区间。

注意,字符串的位置从 1 开始编号。

输出格式

对于每个询问输出一个结果,如果两个字符串子串完全相同则输出 Yes,否则输出 No。

每个结果占一行。

数据范围

1≤𝑛,𝑚≤10^5

输入样例:

8 3
aabbaabb
1 3 5 7
1 3 6 8
1 2 1 2

输出样例:

Yes
No
Yes

代码
#include <iostream>

using namespace std;
typedef unsigned long long ULL;

const int N = 100010,P = 131;
char str[N];
ULL h[N], p[N];//p数组用来存储p的多少次方的

ULL get(int l, int r)
{
	return h[r] - h[l - 1] * p[r - l + 1];
}
int main()
{
	int n,m; cin >> n >> m;
	cin >> str + 1;
	p[0] = 1;//p的0次方为1
	for (int i = 1; i <= n; i++)
	{
		p[i] = p[i - 1] * P;
		h[i] = h[i - 1] * P + str[i];
	}


	while (m--)
	{
		int l1, r1, l2, r2;
		scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
		if (get(l1, r1) == get(l2, r2)) cout << "yes";
		else cout << "NO";
	}

	return 0;
}

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

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

相关文章

时间数据可视化基础实验(南丁格尔玫瑰图)——Python热狗大胃王比赛数据集

【实验名称】 实验一&#xff1a;时间数据的可视化 【实验目的】 1.掌握时间数据在大数据中的应用 2.掌握时间数据可视化图表表示 3. 利用python程序实现堆叠柱形图的可视化 【实验原理】 时间是一个非常重要的维度与属性。时间序列数据存在于社会的各个领域&#xff0c;如&a…

金融工程--pine-script 入门

背景 脚本基本组成 策略实现 实现马丁格尔策略 初始化变量&#xff1a;定义初始资本、初始头寸大小、止损百分比、止盈百分比以及当前资本和当前头寸大小等变量。 更新头寸&#xff1a;创建一个函数来更新头寸大小、止损价格和止盈价格。在马丁格尔策略中&#xff0c;每次亏…

若依框架篇-若依集成 X-File-Storage 框架(实现图片上传阿里云 OSS 服务器)、EasyExcel 框架(实现 Excel 数据批量导入功能)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 实现使用 Excel 文件批量导入 1.1 导入功能的前端具体实现 1.2 导入功能的后端具体实现 1.3 使用 EasyExcel 框架实现 Excel 读、写功能 1.4 将 Easy Excel 集成到…

npm、yarn、pnpm的workspaces使用

示例项目中总会遇到npm的packages中出现的workspaces键值对&#xff0c;自己的项目中没接触过这个东西&#xff0c;到底是什么&#xff1f;怎么用的&#xff1f;简单研究记录一下&#xff1a; abbrev是一个npm包&#xff0c;提供缩写展开功能。‌ 当你定义一个缩写后&#xff0…

mac电脑设置chrome浏览器语言切换为日语英语等不生效问题

在chrome中设置了语言&#xff0c;并且已经置顶了&#xff0c;但是不生效&#xff0c;在windows上直接有设置当前语言为chrome显示语言&#xff0c;但是mac上没有。 解决办法 在系统里面有一个单独给chrome设置语言的&#xff1a; 单独给它设定成指定的语言&#xff0c;然后重…

CTFHUB技能树之文件上传——双写后缀

开启靶场&#xff0c;打开链接&#xff1a; 直接指明是双写绕过方法 上传06shaungxie.php&#xff0c;内容如下&#xff1a; 这一步其实最好换成.png或者.jpg或者.gif这三个符合文件格式的要求后缀 用burp抓包改包&#xff1a; 将php改成pphphp后再“Forward”&#xff1a; 上传…

机房巡检机器人有哪些功能和作用

随着数据量的爆炸式增长和业务的不断拓展&#xff0c;数据中心面临诸多挑战。一方面&#xff0c;设备数量庞大且复杂&#xff0c;数据中心内服务器、存储设备、网络设备等遍布&#xff0c;这些设备需时刻保持良好运行状态&#xff0c;因为任何一个环节出现问题都可能带来严重后…

高边坡稳定安全监测预警系统解决方案

一、项目背景 高边坡的滑坡和崩塌是一种常见的自然地质灾害&#xff0c;一但发生而没有提前预告将给人民的生命财产和社会危害产生严重影响。对高边坡可能产生的灾害提前预警、必将有利于决策者采取应对措施、减少和降低灾害造成的损失。现有的高边坡监测技术有人工巡查和利用测…

设计一个html+css+js的注册页,对于注册信息进行合法性检测

综合使用HTML、JavaScript和CSS进行注册页面设计&#xff0c;实现以下若干功能&#xff1a; 注意整个页面的色调和美观使用FramesetTable布局&#xff08;div也可&#xff09;对用户ID和用户名、口令不符合条件及时判断对口令不一致进行及时判断&#xff08;34的及时判断&#…

【AI学习】Mamba学习(十三):简单了解S5模型,S5论文速读

学习了S4模型后&#xff0c;简单看一下S5模型。 来自两篇文章的摘要 苏神在文章《重温状态空间模型SSM&#xff1a;HiPPO的高效计算&#xff08;S4&#xff09;》中简单提到了S5模型&#xff1a; 由于 HiPPO 的推导是基于u(t)是一维函数进行的&#xff0c;所以到目前为止&am…

博弈论 C++

前置知识 若一个游戏满足&#xff1a; 由两名玩家交替行动在游戏进行的任意时刻&#xff0c;可以执行的合法行动与轮到哪位玩家无关不能行动的玩家判负 则称该游戏为一个公平组合游戏。 尼姆游戏&#xff08;NIM&#xff09;属于公平组合游戏&#xff0c;但常见的棋类游戏&…

揭开C++ STL的神秘面纱之string:提升编程效率的秘密武器

目录 &#x1f680;0.前言 &#x1f688;1.string 构造函数 &#x1f69d;1.1string构造函数 &#x1f69d;1.2string拷贝构造函数 &#x1f688;2.string类的使用 &#x1f69d;2.1.查询元素个数或空间 返回字符串中有效字符的个数&#xff1a;size lenth 返回字符串目…

micro-app【微前端实战】主应用 vue3 + vite 子应用 vue3+vite

micro-app 官方文档为 https://micro-zoe.github.io/micro-app/docs.html#/zh-cn/framework/vite 子应用 无需任何修改&#xff0c;直接启动子应用即可。 主应用 1. 安装微前端框架 microApp npm i micro-zoe/micro-app --save2. 导入并启用微前端框架 microApp src/main.ts …

2024软考网络工程师笔记 - 第8章.网络安全

文章目录 网络安全基础1️⃣网络安全威胁类型2️⃣网络攻击类型3️⃣安全目标与技术 &#x1f551;现代加密技术1️⃣私钥密码/对称密码体制2️⃣对称加密算法总结3️⃣公钥密码/非对称密码4️⃣混合密码5️⃣国产加密算法 - SM 系列6️⃣认证7️⃣基于公钥的认证 &#x1f552…

为微信小程序换皮肤之配置vant

微信小程序自带的控件虽然具有很好的通用性和简洁性&#xff0c;但在面对一些复杂的交互场景和个性化的设计需求时&#xff0c;可能会显得力不从心。其功能的相对基础使得开发者在实现诸如多步骤复杂表单提交、实时数据交互与可视化展示、高度定制化的界面布局等方面&#xff0…

Navicat 安装

Navicat 安装步骤

qt 下载安装

1. 官网地址 https://www.qt.io/ 2. 下载 使用邮箱注册账号&#xff0c;登录&#xff0c;后边安装时也用的到 登录后&#xff1a; 这里需要电话号验证&#xff0c;电话号需要正确的&#xff0c;其他随便填&#xff0c;电话号中国区前需要86&#xff0c; 验证后自动下载 …

[CSP-J 2023] 一元二次方程(模拟)

变态的大模拟…… 洛谷题目传送门https://www.luogu.com.cn/problem/P9750 解题思路 主要还是模拟&#xff0c;题目让你求啥你就求啥&#xff0c;要注意细节。 然后化简根式的可以用质因数分解一下即可。 代码 #include<bits/stdc.h> using namespace std; #define …

opencv 图像翻转- python 实现

在做图像数据增强时会经常用到图像翻转操作 flip。 具体代码实现如下&#xff1a; #-*-coding:utf-8-*- # date:2021-03 # Author: DataBall - XIAN # Function: 图像翻转import cv2 # 导入OpenCV库path test.jpgimg cv2.imread(path)# 读取图片 cv2.namedWindow(image,1) …

C++基础与实用技巧第三节:内存管理与性能优化

第二章&#xff1a;C基础与实用技巧 第三节&#xff1a;内存管理与性能优化 1. 动态内存的管理策略与技巧 动态内存管理是C编程的核心部分之一&#xff0c;合理管理内存可以极大提高程序的性能和稳定性。在C中&#xff0c;动态内存的分配和释放通常使用new和delete运算符&am…