字符串哈希 [模板+公式]

本文详细介绍了三种字符串哈希算法:自然溢出法、单哈希法和双哈希法,以及如何使用它们计算字符串子串的哈希值。此外,还展示了如何利用哈希算法判断回文串。这些方法对于字符串处理和搜索具有较高的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define maxn 5005 

char s[maxn];
int n;
/*
规定:idx(si) = si-'a'+1 
*/

/*
自然溢出法,速度更快 

hash[i]表示0~i字串的哈希值
p[i]为base^i次方

公式:hash[i] = hash[i-1]*base + idx(s[i]) 
*/ 

ull base = 13331;
ull hash[maxn],p[maxn];
void init()
{
//	memset(hash,0,sizeof(hash));
//	memset(p,0,sizeof(p));
	for(int i=0;i<=n;++i)
	{
		hash[0] = 0;
		p[0] = 0;
	}
	hash[0] = 0;
	p[0] = 1;
	
	for(int i=0;i<n;++i)  //0~n
		hash[i+1] = hash[i]*base + (s[i]-'1'+1);
	
	for(int i=1;i<n;++i) //0~n-1
		p[i] = p[i-1]*base;
		
	//区间[l,r]对应的哈希值:
//	ull res = hash[r]-hash[l-1]*p[r-l+1];
}
ull get(int l,int r)
{
	return hash[r] - hash[l-1]*p[r-l+1];
}
/*
单哈希法:
公式:hash[i] = (hash[i-1]*base + idx(s[i]))%mod 
*/
ll base = 29;
ll mod = 1e9+7;
ll hash[maxn],p[maxn];
void init()
{
	int n = strlen(s);
	hash[0] = 0;
	p[0] = 1;
	for(int i=0;i<n;++i)
		hash[i+1] = (hash[i]*base + (s[i]-'a'+1))%mod;
	
	for(int i=1;i<n;++i)
		p[i] = (p[i-1]*base)%mod;
	
	//区间[l,r]对应的哈希值:
	ll res = ((hash[r]-hash[l-1]*p[r-l+1])%mod+mod)%mod;
}

/*
双哈希法:冲突概率更小 
公式:
//hash1[i] = (hash1[i-1]*base1 + idx(s[i]))%mod1 
//hash2[i] = (hash2[i-1]*base2 + idx(s[i]))%mod2 
//*/
ll base1 = 29;
ll base2 = 131;
ll mod1 = 1e9 + 7;
ll mod2 = 1e9 + 9;
ll hash1[maxn],hash2[maxn];
ll p1[maxn],p2[maxn];
void init()
{
	int n = strlen(s);
	hash1[0] = 0,hash2[0] = 0,p1[0] = 1,p2[0] = 1;
	for(int i=0;i<n;++i)
	{
		hash1[i+1] = (hash1[i]*base1 + (s[i]-'a'+1))%mod1;
		hash2[i+1] = (hash2[i]*base2 + (s[i]-'a'+1))%mod2;
	}
	
	for(int i=1;i<n;++i)
	{
		p1[i] = (p1[i-1]*base1)%mod1;
		p2[i] = (p2[i-1]*base2)%mod2;
	}
	
	//同单哈希,但需要两次 
}
/*
正反哈希:可用于判断回文串 
*/
ll base = 29;
ll mod = 1e9+7;
ll hash1[maxn],hash2[maxn];
ll p[maxn];
void init()
{
	memset(hash1,0,sizeof(hash1));
	memset(hash2,0,sizeof(hash2));
	memset(p,0,sizeof(p));
	p[0] = 1;
	for(int i=0;i<n;++i)
	{
		hash1[i+1] = (hash1[i]*base+(s[i]-'a'+1))%mod;
		hash2[i+1] = (hash2[i]*base+(s[n-i-1]-'a'+1))%mod;
	}
	for(int i=1;i<n;++i) p[i] = (p[i-1]*base)%mod;
}
ll get1(int l,int r)
{
	return ((hash1[r]-hash1[l-1]*p[r-l+1])%mod+mod)%mod;
} 
ll get2(int l,int r)
{
	return ((hash2[r]-hash2[l-1]*p[r-l+1])%mod+mod)%mod;
}
bool check(int l,int r)  //判断回文串 
{
	if(get1(l,r)==get2(n-r+1,n-l+1))
	return true;
	return false;
}
int main()
{
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值