[数据结构]哈希表、字符串哈希

哈希表

哈希表: 通过键快速查找到对应的值的数据结构。

实现方法: 为了方便实现, 使用模运算实现, 通常除数使用质数, 从而减少哈希冲突的概率

冲突处理:

  • 开放寻址法
  • 拉链法

拉链法

对于哈希到相同槽位的不同关键字,用一个链表将它们串联起来

cpp 复制代码
#include <iostream>
#include <cstring> 
using namespace std;

const int N = 100003; 
int a[N], h[N], ne[N], idx = 1;
//a是存储数据的节点
//h是头节点
//ne是节点的下一个节点的下标
//全部值都共用一个数组,也就是得出下标不同的数据共用一个数组但使用不同的位置

void insert(int x)
{
	int k = (x % N + N) % N; 
	ne[idx] = h[k];
	a[idx] = x;
	h[k] = idx++;
}

bool query(int x)
{
	int k = (x % N + N) % N; 
	for (int i = h[k]; i != 0; i = ne[i]) 
		if (a[i] == x)
			return true;
	return false;
}

int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		char chr;
		int x;
		cin >> chr >> x;
		if (chr == 'I')
			insert(x);
		else
		{
			if (query(x))
				cout << "Yes\n";
			else
				cout << "No\n";
		}
	}
	return 0;
}

开放寻址法

空间通常要开大2~3倍

如果下标已经有数据就找下标+1的位置存储数据

cpp 复制代码
#include <iostream>
#include <cstring> //(注:原文缺少)
using namespace std;

const int N = 300007, null = 0x3f3f3f3f;
int a[N];

int find(int x)
{
	int k = (x % N + N) % N; 
	while (a[k] != null && a[k] != x)
	{
		k++;
		if (k == N)k = 0;
	}
	return k;
}

int main()
{
	int n;
	cin >> n;
	memset(a, 0x3f, sizeof(a));
	while (n--)
	{
		char chr;
		int x;
		cin >> chr >> x;
		int k = find(x);
		if (chr == 'I')
			a[k] = x;
		else
		{
			if (a[k] == x)cout << "Yes\n";
			else cout << "No\n";
		}
	}
	return 0;
}

字符串哈希方式

字符串前缀哈希法 把字符串看成是一个p进制的数, ( A B C D ) p ( m o d Q ) ( A B C D )_p \pmod Q (ABCD)p(modQ),

  • 取值 : 通常取值 P=131或13331, Q= 2 64 2^{64} 264, 用unsigned long long 当溢出的时候就相当于取模。

作用: 方便求任意区间内的哈希值 -> 快速判断两个字符串是否相同

  • [l,r] -> h ( r ) − h ( l − 1 ) ⋅ p r − l + 1 h(r)-h(l-1) \cdot p^{r-l+1} h(r)−h(l−1)⋅pr−l+1

841. 字符串哈希 - AcWing题库

cpp 复制代码
#include <iostream>
using namespace std;

typedef unsigned long long ULL;

const int N = 100010, P = 131;
char c[N];
ULL h[N], p[N];

ULL get(int l, int r)
{
	return h[r] - h[l - 1] * p[r - l + 1];
}

int main()
{
	int n, m;
	cin >> n >> m >> c + 1;
	p[0] = 1;
	for (int i = 1; i <= n; i++)
	{
		p[i] = p[i - 1] * P;
		h[i] = h[i - 1] * P + c[i];
	}

	while (m--)
	{
		int l1, r1, l2, r2;
		cin >> l1 >> r1 >> l2 >> r2;
		if (get(l1, r1) == get(l2, r2))
			cout << "Yes\n";
		else
			cout << "No\n";
	}
	return 0;
}
相关推荐
延凡科技7 小时前
多场景落地复盘:端边云架构无人机智能巡检系统设计与实践
大数据·数据结构·人工智能·科技·架构·无人机·能源
皓月斯语12 小时前
B3842 [GESP202306 三级] 春游 题解
数据结构·c++·算法·题解
春日见13 小时前
算法与数据结构----哈希表
数据结构·人工智能·算法·机器学习·自动驾驶·哈希算法·散列表
萌动的小火苗13 小时前
嵌入式开发中的栈与队列:任务调度为什么依赖数据结构
数据结构·c++·单片机·嵌入式硬件
叩码以求索13 小时前
统计按位或能得到最大值的子集数目(一)
数据结构·算法
tachibana214 小时前
hot100 数组中的第K个最大元素(215)
java·数据结构·算法·leetcode
星恒随风14 小时前
C++ STL 栈详解:stack 的使用、经典题目与简单模拟实现
开发语言·数据结构·c++·笔记·学习
txzrxz14 小时前
单调队列讲解
数据结构·c++·算法·单调队列
Keven_1115 小时前
算法札记:树状数组的用途
数据结构·算法
cpp_250115 小时前
P1540 [NOIP 2010 提高组] 机器翻译
数据结构·c++·算法·队列·noip·洛谷题解