题意:给定一个主字符串,和一子串,q次查询,每次查询一个区间,问子串在这个区间出现了几次
题解:可以用前缀来记录当前下标之前,子串出现的次数,然后两个前缀数组相减得到结果
(一开始我用的kmp去写,不知道为什么会超时,可能细节没处理好,如果用kmp,也应该预处理记录下每个区间子串出现的次数)
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#define maxn 1005
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
int n,m,k;
string s,t;
int pre[maxn];
int main()
{
cin>>n>>m>>k;
cin>>s>>t;
s=" "+s;
t=" "+t;
for(int i=1;i<=n;i++)//计算前缀
{
int flag=1;
for(int j=1;j<=m;j++)//匹配子串来确定前缀值
{
if(s[i+j-1]!=t[j])
{
flag=0;
break;
}
}
if(flag==1)
{
pre[i]=pre[i-1]+1;
}
else
pre[i]=pre[i-1];
}
for(int i=0;i<k;i++)
{
int l,r;
cin>>l>>r;
if(r-l+1<m)
cout << 0 << endl;
else
cout << pre[r-m+1]-pre[l-1] << endl;
}
return 0;
}
还有一种方法使用string类里面的substr来做,s.substr(i,m)是取s中i下标开始的m个字符的字符串
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#define maxn 1005
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
int n,m,k;
string s,t;
int ans[maxn];
int main()
{
cin>>n>>m>>k;
cin>>s>>t;
for(int i=0;i<n&&i+m<=n;i++)
{
if(s.substr(i,m)==t)
ans[i]=1;
}
for(int i=0;i<k;i++)
{
int l,r;
cin>>l>>r;
int res=0;
for(int i=l-1;i<=r-m;i++)
{
res+=ans[i];
}
cout << res << endl;
}
return 0;
}