kmp

扩展kmp算法

亡梦爱人 提交于 2019-11-26 17:08:15
原文章: https://blog.csdn.net/dyx404514/article/details/41831947 拓展kmp是对KMP算法的扩展,它解决如下问题: 定义母串S,和字串T,设S的长度为n,T的长度为m,求T与S的每一个后缀的最长公共前缀,也就是说,设extend数组,extend[i]表示T与S[i,n-1]的最长公共前缀,要求出所有extend[i](0<=i<n)。 注意到,如果有一个位置extend[i]=m,则表示T在S中出现,而且是在位置i出现,这就是标准的KMP问题,所以说拓展kmp是对KMP算法的扩展,所以一般将它称为扩展KMP算法。 下面举一个例子,S=”aaaabaa”,T=”aaaaa”,首先,计算extend[0]时,需要进行5次匹配,直到发生失配。 从而得知extend[0]=4,下面计算extend[1],在计算extend[1]时,是否还需要像计算extend[0]时从头开始匹配呢?答案是否定的,因为通过计算extend[0]=4,从而可以得出S[0,3]=T[0,3],进一步可以得到 S[1,3]=T[1,3],计算extend[1]时,事实上是从S[1]开始匹配,设辅助数组next[i]表示T[i,m-1]和T的最长公共前缀长度。在这个例子中,next[1]=4,即T[0,3]=T[1,4],进一步得到T[1,3]=T[0,2

kmp模板

℡╲_俬逩灬. 提交于 2019-11-26 14:05:31
#include <iostream> #include <bits/stdc++.h> using namespace std; string a,b; const int maxn = 1e6+10; int ne[maxn],n,m; vector <int> Q; void getne(string s) { ne[1]=0; for (int i=2;i<=m;i++) { int k=ne[i-1]; if (s[k+1]==s[i]) ++k; else { while (k>0&&s[k+1]!=s[i]) k=ne[k]; if (s[k+1]==s[i]) ++k; } ne[i]=k; } return; } void kmp(string s,string t) { getne(t); int k=0; for (int i=1;i<=n;i++) { if (t[k+1]==s[i]) ++k; else { while(k>0&&t[k+1]!=s[i]) k=ne[k]; if (t[k+1]==s[i]) ++k; } if (k==m) { Q.push_back(i-m+1); k=ne[k]; } } } int main() { cin>>a>>b; n=a.size();m=b.size(); a="0"+a; b="0"+b; kmp(a

Cyclic Nacklace HDU - 3746(KMP中对next数组的理解)

时间秒杀一切 提交于 2019-11-26 12:25:12
CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, without any surprise, there are only 99.9 yuan left. he is too distressed and thinking about how to tide over the last days. Being inspired by the entrepreneurial spirit of “HDU CakeMan”, he wants to sell some little things to make money. Of course, this is not an easy task. As Christmas is around the corner, Boys are busy in choosing christmas presents to send to their girlfriends. It is believed that chain bracelet is a good choice. However, Things are not always so simple, as is known to

Luogu P3375 【模板】KMP字符串匹配

时光毁灭记忆、已成空白 提交于 2019-11-26 12:08:22
第一次写kmp是2月,写错但AC了...第二次是6月,才发现... 现在是8月,第三次 /cy 传送门 KMP (D.E. K nuth - J.H. M orris - V.R. P ratt) 也叫看… ,是一种改进的字符串匹配算法,核心是在匹配失败后减少已经匹配过的部分重新匹配。 原理 KMP是通过一个f[](fail)——或者叫next的“失配函数”来实现的。 把已经给出的串称为文本串,要在文本串中找的串称为模式串。 首先,求出 模式串 的失配函数。 fail函数的含义是:在到这一位为止,前缀=后缀的最长长度是多少。 这里的=是指完全相同,比如ABCABC这样的,而不是对称,并且可以有重叠。 特别地,前两位(f[0],f[1])为零。 比如串$ABABAC$,它的fail应该为$001230$ (ABA和ABA重叠了也没事)。 假设已经求好了fail,那么,假设有文本串$ABABABAC$。 $ABABABAC$ $ABABAC$ ←到这里,发现配不上了 $ABABABAC$   $ABABAC$ ←退回到第三位,再试试 $ABABABAC$ $ABABAC$ ←成功 实现 求失配函数 求失配函数是一个自己和自己匹配的过程。 void getf() { f[0] = f[1] = 0; for(int i = 1; i < len2; i++) { int j = f[i]

hdu2087&mdash;&mdash;kmp经典变形题(求不可重叠模式串出现次数)

可紊 提交于 2019-11-26 04:44:52
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2087 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。 Output 输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。 Sample Input abcde a3 aaaaaa aa # Sample Output 0 3 这个题和上一个题差不多,可以参考我的这篇博文: https://blog.csdn.net/qq_43472263/article/details/98752602 不过这里模式串在匹配串里是不能重叠的,所以回溯的时候直接回溯到0的位置,其他和上个题基本一样。 #include <iostream> #include<cstring> using namespace std; const int maxn=1e6+5; inline int read(){ int s=0,w=1; char ch