HDU题目
求目标串s中包含多少个模式串p
KMP算法,必须好好利用next数组,,
//写法一:
#include<string> #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> using namespace std; void getNext(char *p,int *next) { int j,k; int lenp=strlen(p); next[0]=-1; j=0; k=-1; while(j < lenp) { if(k==-1||p[j]==p[k]) //匹配的情况下,p[j]==p[k] { ++j; ++k; //若p[j]==p[k],则需要修正 if(p[j]==p[k]) next[j]=next[k]; else next[j]=k; } else //p[j]!=p[k] k=next[k]; } } int KMPMatch(char *s,char *p)//返回s中包含p的个数 { int next[10010]; //注意next数组的长度要和匹配的字符串长度一样 int lens=strlen(s),lenp=strlen(p); int i,j,ans=0; i=0; j=0; getNext(p,next); while( i < lens ) { if(j==-1||s[i]==p[j]) { i++; j++; } else j=next[j]; //消除了指针i的回溯 if(j==lenp) { ans++; j=next[j]; //再根据next数组从"前"一个找起,防超时,, } } return ans; } char str[1000010],word[10010]; int main() { int n; scanf("%d",&n); while(n--) { scanf("%s%s",word,str); int ans = KMPMatch(str,word); printf("%d ",ans); } return 0; }
//写法二:
#include <stdio.h> #include <string.h> int lens,lenp; char s[1000005]; char p[10005]; int next[10005]; void get_next(int lenp, char *p, int *next)//求next数组 { int i,j; j=-1; next[0]=-1; for (i=1;i<lenp;i++) { while(j>=0 && p[j+1]!=p[i]) j=next[j]; if (p[j+1]==p[i]) j++; next[i]=j; } } int kmp_num(char *s, char *p, int lens,int lenp) //返回s当中包含多少个p { int i,j,cnt; cnt=0; j=-1; for (i=0;i<lens;i++) { while(j>=0 && p[j+1]!=s[i]) j=next[j]; if (p[j+1]==s[i]) j++; if (j==lenp-1) cnt++; } return cnt; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%s",p); scanf("%s",s); lens=strlen(s); lenp=strlen(p); get_next(lenp,p,next); printf("%d ",kmp_num(s,p,lens,lenp)); } return 0; }