字符串哈希映射(回文查询)
(多次判断区段字符串是不是回文)
1、应用情景
给定一个文本字符串s,需要q次查询以的子串是不是回文字符串。
2、原理
将字符串的每一个子串映射成一个数字(一般用unsigned long long自动取模),也就是说对于每一个不同子串,他们所对应的数字大概率是不同的。
3、实现
同过正序哈希映射和逆序哈希映射,可以实现对每一个子串的回文验证。
4、哈希函数
以正向为例
5、代码实现
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N=1e6+5;//N为字符串长度规模
ull h1[N];//正向哈希
ull h2[N];//反向哈希
ull base=233;//base表示进制 用大质数减少hash碰撞
ull p[N];//存储进制位数 如以24进制p[3]=24^3
char s[N];//文本字符串
void solve()
{
cin>>(s+1);//从1读取文本字符串 方便处理
//预处理
int n=strlen(s+1);//字符串长度如abc n=3
p[0]=1;h1[0]=0;h2[0]=0;
for(int i=1;i<=n;i++)
{
h1[i]=(h1[i-1]*base+s[i]);
h2[i]=(h2[i-1]*base+s[n-i+1]);
p[i]=(p[i-1]*base);
}
int q;//q次查询
cin>>q;
while(q--)
{
int l,r;
cin>>l>>r;
if(h1[r]-h1[l-1]*p[r-l+1]==h2[n-l+1]-h2[n-r]*p[r-l+1])
{
cout<<"YES\n";
}
else
{
cout<<"NO\n";
}
}
}
int main()
{
solve();
}
6、判断依据
将子串的正向hash值与反向hash值比较相等则说明回文