mark一下,重新温习了 KMP
KMP复杂度O(n+m)
这里有一个解释的超级的好的博客,大家可以去看一下:http://blog.csdn.net/v_july_v/article/details/7041827
换言之,对于给定的模式串:ABCDABD,它的最大长度表及next 数组分别如下:
根据最大长度表求出了next 数组后,从而有
失配时,模式串向右移动的位数为:失配字符所在位置 - 失配字符对应的next 值
void GetNext(char* p,int next[])
{
int pLen = strlen(p);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen )
{
//p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k])
{
++k;
++j;
next[j] = k;
}
else
{
k = next[k];
}
}
}
-
int KmpSearch(char* s, char* p) { int i = 0; int j = 0; int sLen = strlen(s); int pLen = strlen(p); while (i < sLen && j < pLen) { //①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++ if (j == -1 || s[i] == p[j]) { i++; j++; } else { //②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j] //next[j]即为j所对应的next值 j = next[j]; } } if (j == pLen) return i - j; else return -1; }
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,m;
int a[1000005]; //匹配串
int b[1000005]; //模式串
int next[1000005];
void get_next(){
next[0]=-1;
int k=-1;
int j=0;
while(j<m){
//b[k]表示前缀,b[j]表示后缀
if(k==-1 || b[j]==b[k]){
++k;
++j;
next[j]=k;
}
else{
k=next[k];
}
}
}
int kmp(){
int i=0,j=0;
while(i<n&&j<m){
//①如果j = -1,或者当前字符匹配成功(即a[i] == b[j]),都令i++,j++
if(j==-1||a[i]==b[j]){
i++;
j++;
}
else{
j=next[j];
}
}
if(j==m) return i-j+1;
else return -1;
}
int main(){
int i,t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(i=0;i<n;i++) scanf("%d",&a[i]);
for(i=0;i<m;i++) scanf("%d",&b[i]);
get_next();
int ans=kmp();
printf("%d\n",ans);
}
return 0;
}
hdu 2203 同样是模板题
#include<stdio.h>
#include<string.h>
int n,m;
char a[200005]; //匹配串
char b[200005]; //模式串
int next[200005];
void get_next(){
next[0]=-1;
int k=-1;
int j=0;
while(j<m){
//b[k]表示前缀,b[j]表示后缀
if(k==-1 || b[j]==b[k]){
++k;
++j;
next[j]=k;
}
else{
k=next[k];
}
}
}
int kmp(){
int i=0,j=0;
while(i<n&&j<m){
//①如果j = -1,或者当前字符匹配成功(即a[i] == b[j]),都令i++,j++
if(j==-1||a[i]==b[j]){
i++;
j++;
}
else{
j=next[j];
}
}
if(j==m) return i-j+1;
else return -1;
}
int main(){
int i,t;
while(gets(a)){
n=strlen(a);
for(i=0;i<n;i++){
a[i+n]=a[i];
}
n=2*n;
gets(b);
m=strlen(b);
get_next();
int ans=kmp();
if(ans==-1){
printf("no\n");
}
else{
printf("yes\n");
}
}
return 0;
}