哈希表
哈希函数,把一个大的范围,映射为一个小的范围
离散化是一种特殊的哈希方式
用于对数据的快速插入和读取
存储结构(处理冲突)
拉链法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| int h[N], e[N], ne[N], idx;
void insert(int x) { int k = (x % N + N) % N; e[idx] = x; 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 = ne[i]) if (e[i] == x) return true;
return false; }
|
![20220113161351]()
![20220113161312]()
开放寻址法(常用)
开数组时要大2~3倍
1 2 3 4 5 6 7 8 9 10 11 12 13
| int h[N];
int find(int x) { int t = (x % N + N) % N; while (h[t] != null && h[t] != x) { t ++ ; if (t == N) t = 0; } return t; }
|
![开放寻址法]()
字符串哈希
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 核心思想:将字符串看成P进制数,P的经验值是131或13331,取这两个值的冲突概率低 小技巧:取模的数用2^64,这样直接用unsigned long long存储,溢出的结果就是取模的结果
typedef unsigned long long ULL; ULL h[N], p[N];
p[0] = 1; for (int i = 1; i <= n; i ++ ) { h[i] = h[i - 1] * P + str[i]; p[i] = p[i - 1] * P; }
ULL get(int l, int r) { return h[r] - h[l - 1] * p[r - l + 1]; }
|
![20220113172122]()