首页 > 其他分享 >7、哈希表

7、哈希表

时间:2024-10-27 15:19:49浏览次数:3  
标签:输出 映射 10 int 哈希 字符串

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
题目描述 字符串哈希

给定一个长度为

标签:输出,映射,10,int,哈希,字符串
From: https://blog.csdn.net/weixin_73378557/article/details/143244900

相关文章

  • 「哈希表」是什么,有哪些常用的解决冲突的方法
    哈希表(HashTable),也被称为散列表,是一种数据结构,用于实现关联数组(AssociativeArray)或映射(Map)这样的抽象数据类型。常用的解决哈希表冲突的方法:1.链地址法(SeparateChAIning);2.开放寻址法(OpenAddressing);3.线性探查(LinearProbing)等。一、哈希表是什么哈希表(HashTable),也被称......
  • 散列表(哈希表)
    基本思想以数据对象的关键字key为自变量,通过一个确定的函数关系h,计算出对应的函数值h(key),把这个值解释为数据对象的存储地址,并按此存放,即存储位置=h(key)装填因子设散列表空间大小为m,填入表中的元素个数是n,则装填因子a=n/m,常见散列表大小设计使得a=0.5~0.8为宜装填因子有什......
  • 字符串哈希 学习笔记
    两种哈希的表示方式。设\(s_i\)为字符串内第\(i\)位,\(h_i\)表示字符串内\([1,i]\)的哈希值,\(p\)为模数,那么第一种哈希方式是:\(h_i=h_{i-1}*p+s_i\),即把\(h_i\)当作一个\(p\)进制数,加入\(s_i\)时在数的末尾。\(h_i=h_{i-1}+s_i*p^{i-1}\),即是在开头加入\(s_i\)......
  • 浅谈哈希及一类应用杂题
    浅谈哈希及一类应用杂题关于哈希的一些另类想法PS:与后文实际应用无关哈希的目的本质就是比较两个无法直接比较是否相同的一些东西,通过赋值来使其获得比较大小的能力,然后就想能不能搞一个随手就能整出来还不容易被卡常数比如之前好多题卡\(131\)什么的。如果我的数是纯随机的......
  • 哈希碰撞
    问:两个字符串hashcode相同equals一定相同吗?equals相同hashcode一定相同吗?答:equals相同hashcode一定相同,hashcode因为哈希碰撞所以equals不一定相同。Hash如何存数据hash表的本质其实就是数组,hash表中通常存放的是键值对Entry。如下图:  这里的学号是个key,哈希表就是根据k......
  • NOIP2024集训Day57 哈希
    NOIP2024集训Day57哈希A.[CF213E]TwoPermutations考虑到都是排列,值域连续,于是\(a\)都加\(x\)之后相当于在值域上平移了一段,也是连续的。由于要进行比较,个很容易想到哈希。\(a\)的哈希值很好维护,每次平移一位加上\(\sumbase^i\)即可。考虑如何快速取出\(b\)中在......
  • 在 Git 中,获取提交的哈希值(commit hash)
    在Git中,获取提交的哈希值(commithash)的方法有多种。以下是一些常用的方法:1.使用gitlog命令你可以使用gitlog命令查看提交历史,其中包括每个提交的哈希值。gitlog这将输出类似以下的内容:commit8927698069e9c719f452d7a71faac23ef25d27ab(HEAD->main)Auth......
  • 算法专题九: 哈希表与字符串
    目录哈希表1.两数之和2.判断是否为字符重拍排3.是否存在重复元素4.存在重复元素Ⅱ5.字母异位词分组字符串1.最长公共前缀2.最长回文子串3.二进制求和4.字符串相乘哈希表1.两数之和固定一个数,找前面有没有target-x这个数,使用哈希表,每次查找之后......
  • 【题解】Solution Set - NOIP2024集训Day56 哈希杂题
    【题解】SolutionSet-NOIP2024集训Day56哈希杂题https://www.becoder.com.cn/contest/5640「CF568C」NewLanguage做过的2-sat。「NOI2024」集合做过。做法见提交记录。「CSP-S2022」星战简要题意:给定有向图。修改使一条边失效/恢复;使一个点的所有入边......
  • 哈希扩展攻击
    这辈子没想过web手要学这东西...原理md家族的哈希运算是分块运算的.也就是说用前面的密文和当前模块的明文拼接以后进行哈希运算得到当前模块的密文.原理说起来复杂,直接说怎么应用.设secret为已知长度但不知道具体内容的秘钥,一段已知明文data,希望追加的明文append.那么我们......