KMP算法 hdu 1711 hdu 2203

来源:互联网 发布:网络安全工程师 编辑:程序博客网 时间:2024/05/16 07:55

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];          }      }  }  



  1. 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;  } 


hdu 1711模板题



#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;}


0 0
原创粉丝点击