标签:kmp
关于字符串的AC自动机,KMP,Trie树,后缀数组。
KMP是基础。当一个字符串与模式串匹配的时,若失配,利用前面匹配的信息,利用三部分连等关系。可以滑动的“恰如其分”。
Next数组的求法:
若此时求的是next[i]的数值,j位置之前的与从i开始后j-1个字符都是匹配的,若s[i]==s[j] 那么next[++i]=++j; 若不相等可以j=next[j]滑动回去。
OK,那么什么时候匹配串滑动?我们设定next[0]=-1,当一直回溯到0还不匹配就滑动吧。
发一道模板题 HDU 1686
#include<algorithm> #include<iostream> #include<iterator> #include<cstdlib> #include<cstring> #include<cstdio> #include<map> #define inf (1<<30) #define mem(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=10+100; int N,M; #define N 30+10000 int next[N]; void getNext(char *s) { int i = 0, j = -1; next[0] = -1; int len=strlen(s); while(i != len) { if(j == -1 || s[i] == s[j]) { ++i,++j; if(s[i]!=s[j]) next[i] =j; else next[i]=next[j]; } else j = next[j]; } } int KMP(char *s1, char *s2) { int i=0,j=0; int len1=strlen(s1),len2=strlen(s2); int res=0; while(i<len2) { if(j==-1 || s1[j]==s2[i]) i++,j++; else j=next[j]; if(j==len1) res++,j=next[j]; } return res; } char s1[11000],s2[1100000]; int main() { int T; scanf("%d",&T); getchar(); while(T--){ gets(s1);gets(s2); getNext(s1); printf("%d\n",KMP(s1,s2)); } return 0; }
标签:kmp
原文地址:http://blog.csdn.net/gg_gogoing/article/details/41214401