字符串匹配

【题目描述】

  给你两个串A,B,可以得到从A的任意位开始的子串和B匹配的长度。给定K个询问,对于每个询问给定一个x,求出匹配长度恰为x的位置有多少个。N,M,K<=200000

【解】

  这是道非常好的kmp题,感觉做了之后对kmp有了新认识。。。看到马上kmp,首先当我们在A串上用B串跑一遍kmp,我们会得到一个数组,也就是在A串上以i为结尾的字串长度为A[i]的后缀等于B串长度为A[i]的前缀。那么在这个时候我们用一个cnt数组统计每个长度出现的次数。但统计完我们发现我们还漏了一些,因为B里会有后面的字串和开头字串一样的情况,而原始数组统计的是最大匹配长度,这个时候我们可以利用B串的自匹配数组。

for (i = m; i >= 1; i--)
    cnt[kmp[i]] += cnt[i];//kmp是B的自匹配数组

因为B串的前kmp[i]位和后kmp[i]为是一样的,也就是说当A串和B串的i位匹配时,以i为结尾的后kmp[i]位也可以和B串的前kmp[i]位匹配,原始数组因为统计的最大匹配长度漏统计了这种情况,进行该项操作后就不会漏掉了。

最后因为题目要求匹配长度恰好为x,然而cnt数组中存储的cnt[i],必然包含了cnt[i + 1]及以上的情况,所以我们输出的时候输出cnt[i] - cnt[i + 1],因为cnt[i]中可以扩展的字串必然都包含于cnt[i + 1]。

转载于:https://www.cnblogs.com/hyl2000/p/5904082.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值