\[哈希表 \begin{cases} 存储结构 \begin{cases} 开放寻址法 \\[2ex] 拉链法 \\[2ex] \end{cases} \\[3ex] 字符串哈希方式\\[3ex] \end{cases} \]
一般哈希
开放寻址法
//开放寻址法模板
const int N=(数据范围的2~3倍,质数),null=(数据范围外的数,常用0x3f3f3f3f);
int h[N];
memset(h,null,sizeof h);
//如果x在哈希表中,返回x的下标;如果x不在哈希表中,返回x应该插入的位置
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;
}
拉链法
//拉链法模板
int h[N],e[N],ne[N],idx;
memset(h,-1,sizeof h); //将单数组每个点的指针初始化为空指针-1
//向哈希表中插入一个数
void insert (int x)
{
int k=(x%N+N)%N; //保证k为非负数
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;
}
字符串哈希
核心思想: 将字符串看成 p 进制数, p 的经验值是
131
或13331
, 取这两个值冲突概率低
小技巧: 取模的数用 \(2^{64}\) , 这样直接用
unsigned long long
存储, 溢出的结果就是取模的结果
//字符串哈希模板
const int p=131;
unsigned long long h[N],p[N];
//h[k]存储字符串前k个字母的哈希值,p[k]存储(p^k)%(2^64)
//初始化
p[0]=1;
for(int i=1;i<=n;i++)
{
h[i]=h[i-1]*p+str[i];
p[i]=p[i-1]*p;
}
//计算子串str[l~r]的哈希值
unsigned long long get (int l,int r)
{
return h[r]-h[l-1]*p[r-l+1];
}
标签:idx,int,long,哈希,表中,cases From: https://www.cnblogs.com/evilboy/p/17364387.html