算法笔记6.Hash表,STL使用简介

本文详细介绍了哈希表的基本原理,包括哈希函数的应用、拉链法的存储方式(使用一维数组和链表解决冲突)、开放寻址法的实现,以及字符串哈希的前缀哈希法。同时提及了如何在实际编程中使用STL中的相关数据结构,如vector、string等。
摘要由CSDN通过智能技术生成

Hash表

简介

最主要的作用就是把一个比较大的值域映射到一个比较小的空间。一般就是有一个哈希函数定义一个规则,输入一个大的数,输出一个小的数(一般是直接取mol,一般是取成质数,离2远点,这样冲突概率最小)。

但是这个规则有可能会有冲突,比如两个数映射出来是同一个数,这时一般就会用到下面的两种方法

前面写的离散化是一种特殊的哈希方式。

存储方式

拉链法

就是开辟一个一维数组,这个数组的索引就是哈希化以后的结果,我们在这个索引的位置开一条链,下面加上所有的冲突的结果。

假如我们开辟的数组是P,然后11和21哈希化以后的结果都是1,那么就去P[1]处,用一条链式结构存储11和21

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

//插入元素
void insert(int x)
{
	int k = (x % N + N) % N; //确保得到的是正值
	//h中存储的是指向链表的起点的idx,就是在e里面的索引
	//插入一个元素就相当于是插入一个新的头节点,再让h指向一下
	//这样不用去找链表详细内容了
	e[idx] = x;    
	ne[idx] = ne[k];  
	h[k] = idx++;
}

//查找
bool find(int x)
{
	int k = (x % N + N) % N;
	for (int i = h[k]; i != -1; i = ne[i])
		if (e[i] == x)
			return true;
	return false;
}
开放寻址法

开放寻址法也是开一个一维数组,但是长度会开到两到三倍。这样的话,每两个相邻的值之间会有一些位置的空余(相邻不是指数组相邻元素,是相邻值哈希后的两个索引之间),然后我们存值的时候,就检查一下这个位置有没有存,如果存了就去下一个位置(相当于是把拉链法的链子也存到数组里面了)

int N = 100010, null = 0x3f3f3f;
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;
}

字符串哈希

全名叫字符串前缀哈希法,首先我们将这个字符串每一位字符分离出来,然后每一位看成一个p进制的数,再然后将他们转换为十进制的数(乘以一个p的n次方,n由位置决定),因为可能得到数很大,所以再取一个余数。

(一般情况下,0会被舍弃掉,不管是进制的时候还是数组索引的时候,都从1开始)

(一般情况下,进制用131或者13331,对2的64次方取余。这样冲突概率很小)

这个和数字哈希的区别是,数组哈希容忍冲突情况,这个字符串哈希是就当运气好没有冲突

而且我们还有一个好处,如果我们已知一个字符串的哈希值,我们可以算出这个字符串任意一个子串的哈希值.

假如我们已知1~R的哈希值(h[R])和1~L-1的哈希值(假设L在R左边),我们就可以用h[R] - H[L-1]*p的R-L+1次方,得到由L到R的哈希值(因为前缀的计算是从第一位往下算的,也就是说,前面计算的值不管是多少,都不影响需要得到的子串的哈希,只要将幂次方补上就行了)

//这段代码可以得到子串的哈希值
#include <iostream>
using namespace std;

typedef unsigned long long ULL; //定义足够长的长度,这样就不用取模了

const int N = 100010, P = 131;

int n, m;
char str[N];
ULL h[N], p[N];

//得到子串哈希值
ULL GetHash(int l, int r)
{
	return h[r] - h[l - 1] * p[r - l + 1];
}

//预先初始化一下p的x次方数组和子串哈希值数组(数组索引对应前x+1个字符)
void Init(int n)
{
    p[0] = 1;
    for (int i = 1; i <= n; i++)
	{
		p[i] = p[i - 1] * P;
		h[i] = h[i - 1] * P + str[i];
	}
}

STL目录

vector变长数组

string字符串

queue队列

priority_queue优先队列(堆)

stack堆

deque双端队列

set,map,multiset,multimap树形结构(底层是红黑树)

unordered_set,unordersed_map,undordered_multiset,undordered_multimap哈希表

bitset压位

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值