题目链接:https://loj.ac/problem/10034
哈希表的知识:
哈希表是一种高效的数据结构。
例如,我们要存储和使用下面的线性表:A(1,75,324,43,1353,91,40)。
分析这个线性表的元素类型和范围,开一个一维数组A[1,…1353]。使得A[key]=key,即线性表的key这个元素存储在A[key]中。
但是这样造成了空间的浪费,加以优化:
设计一个哈希函数H(key)=key mod 13,然后令A[H(key)]=key,这样一来,定义一个一维数组A[0…12]就足够了。
但是H(1)=H(10)=1,相当于我们在存储40时又把1给覆盖了。
解决的方法:借助邻接表
分析:
先求出字符串的哈希值,模数不能设为2的32次方或2的64次方这样大的数,因为我们要将其用哈希表存储下来。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int mod1 = 1e6 + 3, mod2 = 1e6 + 9, p1 = 47, p2 = 79, N = 30000;
int tot = 1, nxt[N + 5], first[mod1 + 5], en[N + 5];
void inser(int x, int y) /*将元素插入哈希表*/
{
nxt[tot] = first[x];
first[x] = tot;
en[tot] = y;
tot++;
}
int query(int x, int y)
{
for (int i = first[x]; i != -1; i = nxt[i])
{
if (en[i] == y)
return 1;
}
return 0;
}
int main()
{
int n;
char op[10], s[205];
scanf("%d", &n);
memset(first, -1, sizeof(first));
while (n--)
{
scanf("%s", op);
gets(s); /*图书名称*/
int len = strlen(s), sum1 = 0, sum2 = 0;
//计算字符串的哈希值
for (int i = 0; i < len; i++) /*双哈希思想,两个关键字决定一个字符串,减小误差*/
{
sum1 = (sum1 * p1 + s[i]) % mod1;
sum2 = (sum2 * p2 + s[i]) % mod2;
}
if (op[0] == 'a')
inser(sum1, sum2);
else
{
if (query(sum1, sum2))
printf("yes\n");
else
printf("no\n");
}
}
return 0;
}