输入:
几个
插
查
5
I 1
I 2
I 3
Q 2
Q 5
输出:
Yes
No
1拉链法
数组下面拉一个列表,不用怕某个数冲突了,
h[k]一开始是-1没有拉链
2寻址法(推荐,只开一个数组):
find,设置索引k,有哈希值就返回索引给他用,肯定能找到.k=find(x)就是来找有没有地址的;这个k就是后面用的,h[k]=x用来插入的好占据了地方
h[k]装的应该是一个要插入的x
为什么k==0,如图1;防止一上来接近我的0x3f3f3f3f,不能到h[k];为什么不能break,--要看我的目的呀,就是就是要必须找到一个k,一定能找到10的9方呀
为什么要两倍的2的质数
op是字符数组,所以*op代表数组第一个
memset(h,0x3f,sizeof h);为什么不是默认为0x3f3f3f3f.
while(h[k]!=null&&h[k]!=x)就是判断,还是这个--要看我的目的呀,就是就是要必须找到一个k,一定能找到10的9方呀
什么时候进入while,h[k]!=x,h[k]!=null,哈希值有且==x,]哈希值什么时候重复呢
h[k]!=x当然没有x啊,
图1,来自up:_小z学长
#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给他
{
k++;
if(k==N)k=0;//重新搜索)1
}
return k;//h[k]==null&&h[k]==x
}
int main(){
int n;
scanf("%d",&n);
memset(h,0x3f,sizeof h);
while(n--){
char op[2];
int x;
scanf("%s%d",op,&x);
int k=find(x);//给一个k
if(*op=='I')h[k]=x;
else if(h[k]!=null)puts("Yes");
else puts("No");
}
return 0;
}
//5
//I 1
//I 2
//I 3
//Q 2
//Yes
//Q 5
//No