Kmp算法-未完
Posted waryan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kmp算法-未完相关的知识,希望对你有一定的参考价值。
一:Kmp算法
概要:
Kmp算法中nxt数组为重要组成部分,nxt数组所存的内容为:next[i]表示前i个字符组成的子串的最长相同前缀和后缀的长度,要注意应用中提出的nxt[i]变化(方便在匹配两个字符串时候跳动减少时间复杂度)
nxt数组模板:
以i=1为起点的字符串进行处理
void get_nxt() { nxt[0]=nxt[1]=0; for(int i=2,j=0;i<=m;++i){ while(j&&b[j+1]!=b[i]) j=nxt[j];//交换后从头再次匹配前缀和后缀 if(b[j+1]==b[i]) ++j; nxt[i]=j; } }
应用:
求前缀串子串的周期和子串的长度
求前缀串在原串中能匹配的次数
1.POJ-1961 Period
题意:
求字符串的每个前缀串是否有周期,和周期的具体值
若此字符串前缀和后缀相同的情况则会发生nxt[i]连续加的情况
所以求前缀传是否为周期串是会出现叠加的情况,根据叠加情况此时的i-nxt[i]即为所求串的长度,若%为0则满足条件,只需要仔细想想就会发现满足%为0的就是所求的len!因为nex[i]是在前缀后缀相同的情况下会叠加
2.HDU-3336 Count the string
题意:
求一个串的前缀在这个串中有多少个匹配
此题网上很多人的解法都是错误的会有aaa答案是5的情况但其实aaa的答案是6
aaa-a*3-aa*2-aaa
dp[i]=dp[nxt[i]]+1的理解
dp[i]代表的是以第i个字符结尾的前缀串所具有的匹配个数,这个个数就是他所匹配的前缀中有的+上他自己的一个就是他的
比如说dp[8]=dp[3]+1,那么这个以8结尾的前缀串中含有一个长度为3的前缀后缀相同,则他这个后缀匹配个数为前缀所能匹配的相同+1,微小状态的叠加
int main() { int t;scanf("%d",&t); while(t--){ scanf("%d%s",&m,b+1); get_nxt(); dp[0]=0;//相当于初始化了数组 int ans=0; for(int i=1;i<=m;++i){ dp[i]=dp[nxt[i]]+1;//dp dp[i]%=mod; ans=(ans+dp[i])%mod; } printf("%d ",ans); } }
最后放两个学习Kmp时候看的博客
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
https://www.cnblogs.com/SYCstudio/p/7194315.html
以上是关于Kmp算法-未完的主要内容,如果未能解决你的问题,请参考以下文章