考前复习——字符串哈希与哈希表
字符串哈希
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define N 1005
#define ULL unsigned long long
#define Base 13331
int n;
ULL h[N][N],q[N];
char ch[N][N];
inline int read()
{
int x=0;
bool f=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch=='-')
f=0;
for(;isdigit(ch);ch=getchar())
x=(x<<1)+(x<<3)+ch-'0';
return f?x:(~(x-1));
}
void Hash(int k)
{
//计算第k个字符串的哈希值
ULL len=strlen(ch[k]+1);
for(ULL i=1;i<=len;i++)
{
h[k][i]=h[k][i-1]*Base+(ch[k][i]-'A');
}
return ;
}
ULL ck(ULL h[],int l,int r)
{
//获取该字符串[l,r]区间的哈希值
return h[r]-h[l-1]*q[r-l+1];
}
int main()
{
cin>>n;//几个字符串
q[0]=1;
for(int i=1;i<N;i++)q[i]=q[i-1]*Base;
for(int i=1;i<=n;i++)
{
scanf("%s",ch[i]+1);
Hash(i);
}
// cout<<ck(h[1],1,3)<<" "<<ck(h[2],4,6);
return 0;
}
哈希表
现在要存储和使用下面的线性表:A(1,75,324,43,1353,91,40)。
定义一个一维数组 A[1...n],此时 n=7,将表中元素按大小顺序存储在 A[i]中,但这样就算使用二分查找,我们仍需要用 O(log n)的时间去查找某个元素
为了用 O(1)的时间实现查找,可以开一个一维数组 A[],使得 A[key]=key,但这显然会造成空间上的很大浪费,尤其是数据范围很大时。
为了使空间开销减少,我们可以对第二种方法加以优化,设计一个哈希函数 H(key) = key mod 13,然
后令 A[H(key)]=key,这样一来定义一个一维数组 A[0...12]就已足够,这种方法就是哈希表
using namespace std;
const int N = 50000; //定义总共存入哈希表的数字个数
const int b = 999979; //定义哈希函数中的模数
int tot, adj[H], nxt[N], num[N]];
void insert(int key) { //将一个数字插入哈希表
int h = key % b; //除余法
for (int e = adj[h]; e; e = nxt[e]) {
if (num[e] == key) return ;
}
//如果链表中已经出现过当前的数字就不用再存储一遍
nxt[++tot] = adj[h], adj[h] = tot;
num[tot] = key; //建立链表,存储下所有哈希值等于 h 的数字
}
bool query(int key) { //查询数字 x 是否存在于哈希表中
int h = key % b; //同样先进行取余,求其哈希值
for (int e = adj[h]; e; e = nxt[e])
if (num[e] == key) return true; //查询对应链表,查询到则表示存在
return false; //不存在返回 false
}
}
本文来自博客园,作者:pig_pig,转载请注明原文链接:https://www.cnblogs.com/pigAlg/p/17483579.html
浙公网安备 33010602011771号