哈希表
哈希函数
拉链法
模板:
const int N = 100003;
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;
}
开放寻址法
模板:
const int N = 200003, null = 0x3f3f3f3f;
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;
}
整数hash
Acwing840. 模拟散列表
拉链法(运用单链表实现)
#include <iostream>
#include <cstring>
using namespace std;
const int N = 100003;
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;
}
int main()
{
int n;
scanf("%d",&n);
memset(h, -1, sizeof(h));
while (n --)
{
char op[2];
int x;
scanf("%s%d",op,&x);
if (op[0] == 'I')
{
insert(x);
}
if (op[0] == 'Q')
{
if (find(x)) puts("Yes");
else puts("No");
}
}
}
开放寻址法(蹲坑法)
//开放寻址法
#include <iostream>
#include <cstring>
using namespace std;
const int N = 200003,null = 0x3f3f3f3f;
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;
}
int main()
{
int n;
scanf("%d",&n);
memset(h, 0x3f3f, sizeof h);
while (n --)
{
string op;
int x;
cin >> op >> x;
if (op == "I")
{
h[find(x)] = x;
}
if (op == "Q")
{
if (h[find(x)] == null) puts("No");
else puts("Yes");
}
}
}
字符串hash
思路:
AcWing 841. 字符串哈希
注意:
1.不能映射成0
2.运气好,不存在冲突(经验值:进制P一般取131或13331,模取2^64)
小技巧:
unsigned long long会给数据直接模上2^64
//字符串哈希
#include <iostream>
using namespace std;
typedef unsigned long long ULL;
const int N = 100010, P = 131;//P代表进制
char str[N];//读入字符串
ULL h[N], p[N];//h[]存储字符串的hash值,p[]存储进制的多少次方
//ULL会自动将数字模上2^64
ULL get(int l1, int r1)//返回l1到r1之间字符串的hash值
{
return h[r1] - h[l1 - 1] * p[r1 - l1 + 1];
}
int main()
{
int n, m;
scanf("%d%d%s", &n, &m, str + 1 );
p[0] = 1;
for (int i = 1; i <= n; i ++ )
{
h[i] = h[i - 1] * P + str[i];//计算前i个字符的hash值
p[i] = p[i - 1] * P;
}
while (m --)
{
int l1, r1, l2, r2;
scanf("%d%d%d%d", &l1, &r1, &l2, &r2 );
if (get (l1, r1) == get (l2, r2)) puts("Yes");
else puts("No");
}
}
如有错误,欢迎指正!!!