考前复习——字符串哈希与哈希表

字符串哈希

点击查看代码
#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
    }
}
posted @ 2023-06-20 11:57  pig_pig  阅读(18)  评论(0)    收藏  举报