160. 匹配统计

题目链接
cnt[i]表示与模式串匹配长度至少为i的文本串的后缀数目
(此时cnt[x]保存的是匹配长度>=x的位置个数 这样理解更清楚一点)
那么恰好匹配长度为x的数目就是cnt[i]-cnt[i+1],有点后缀和思想
参考题解

#include <bits/stdc++.h>
using namespace std;
void getnext(vector<int>&next, string pattern){
    next[0]=-1;
    int j=-1;
    for(int i=1;i<pattern.size();i++){
        while(j!=-1 && pattern[j+1]!=pattern[i]){
            j=next[j];
        }
        if(pattern[j+1]==pattern[i]){
            j++;
        }
        next[i]=j;
    }
}
int main(){
    
    int n,m,q;
    cin >> n >> m >> q;
    string text,pattern;
    cin >> text >> pattern;
    vector<int> next(m,-1);
    getnext(next,pattern);
    int cnt[200005]={0};
    int j=-1;
    for(int i=0;i<text.size();i++){
        while(j!=-1 && text[i]!=pattern[j+1]){
            j=next[j];
        }
        if(text[i]==pattern[j+1]){
            j++;
        }
        cnt[j+1]++;//pattern[0-j]匹配了text[i-j~i]串,至少匹配长度为j+1,(“至少”是因为下一个字符还可能匹配),同时pattern[0-next[j]]也匹配了text[i-next[j]~i]串...(相当于把以i位置结尾各个至少匹配长度的个数都+1)整体来看,最终cnt[j+1]加几次,cnt[next[j]+1]就会加几次,因此可以最后倒着枚举累加,降低时间复杂度
        if(j==m-1){
            j=next[j];
        }
    }
    for(int i=m;i>=1;i--){
        cnt[next[i-1]+1]+=cnt[i];//i表示匹配的长度,对应到next数组要-1
    }
    for(int i=0;i<q;i++){
        int tmp;
        cin >> tmp;
        cout << cnt[tmp]-cnt[tmp+1] << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值