简要:
主要是以两道题目的形式来学习一下这个两个知识点,前缀哈希表(Acwing第841题)和前缀字符串(Acwing第4312题)
相关题目:
解题思路:
相关代码1:
/*
暴力法,不断地截取字符串,然后进行比较。时间复杂度较高,可能是n^2级别的。
*/
#include<iostream>
#include<string>
using namespace std;
int n,m;
string s;
int l1,r1,l2,r2;
int main(){
cin>>n>>m>>s;
while(m--){
cin>>l1>>r1>>l2>>r2;
string s1=s.substr(l1-1,r1-l1+1);
string s2=s.substr(l2-1,r2-l2+1);
if(s1==s2){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
return 0;
}
相关代码2:
#include<iostream>
#include<string>
using namespace std;
typedef unsigned long long ULL;
int P=131;
//p[i]表示的是第i个字符的权重。
//h[i]表示的是前i个字符的哈希值。
// P = 131 或 13331 Q=2^64,在99%的情况下不会出现冲突
// 使用场景: 两个字符串的子串是否相同
//p[i]可以看成p^i次方
//ge()函数是为了取出区间内的哈希值。
int p[100001],h[100001];
ULL get(int l,int r){
return h[r]-h[l-1]*p[r-l+1];
}
int n,m;
int l1,r1,l2,r2;
string s;
int main(){
cin>>n>>m;
cin>>s;
s=' '+s; //在字符串的首位加上一个空格。
p[0]=1; //p的0次方为1
for(int i=1;i<=n;i++){
p[i]=p[i-1]*P; //算出每一位的权重,位数是从下标0开始的。
h[i]=h[i-1]*P+s[i];
}
while(m--){
cin>>l1>>r1>>l2>>r2;
if(get(l1,r1)==get(l2,r2)){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
return 0;
}
相关题目:
解题思路:
相关代码1:
/*
暴力解法,时间复杂度可能会比较高。
*/
#include<iostream>
#include<string>
using namespace std;
int n,m,q;
string a,b;
int cnt;
int main(){
cin>>n>>m>>q;
cin>>a>>b;
while(q--){
int t1,t2;
cin>>t1>>t2;
string s=a.substr(t1-1,t2-t1+1);
for(int i=0,j=b.size()-1;j<=s.size();i++,j++){
string s1=s.substr(i,j-i+1);
if(s1==b)
cnt++;
}
cout<<cnt<<endl;
cnt=0;
}
return 0;
}
相关代码2:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int n,m,q;
string a,b;
int cnt;
int f[10001];
int main(){
cin>>n>>m>>q;
cin>>a>>b;
reverse(a.begin(),a.end());
a.push_back('0');
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
a.push_back('0');
reverse(b.begin(),b.end());
for(int i=b.size();i<=a.size();i++){
f[i]=f[i-1];
string s1=a.substr(i-b.size()+1,m);
if(s1==b){
f[i]++;
}
}
while(q--){
int t1,t2;
cin>>t1>>t2;
t1+=m-1;
if(t1>t2){
cout<<0<<endl;
}
else{
cout<<f[t2]-f[t1-1]<<endl;
}
}
return 0;
}
相关代码3:
/*
运用前缀哈希表可以来解这道题。
*/
#include<iostream>
#include<string>
using namespace std;
int n,m,q;
string S,T;
typedef unsigned long long ULL;
ULL p[100001],h[100001];
const int P=131;
ULL get(int l,int r){
return h[r]-h[l-1]*p[r-l+1];
}
int main(){
cin>>n>>m>>q;
cin>>S>>T;
T=' '+T;
S=' '+S;
p[0]=1;
for(int i=1;i<=n;i++){
p[i]=p[i-1]*P;
h[i]=h[i-1]*P+S[i];
}
int cmp=0;
for(int i=1;i<=m;i++){
cmp=cmp*P+T[i];
}
while(q--){
int l,r;
int cnt=0;
scanf("%d%d",&l,&r);
for(int i=l;i+m-1<=r;i++){
if(get(i,i+m-1)==cmp){
cnt++;
}
}
cout<<cnt<<endl;
}
return 0;
}