1. 程式人生 > >KMP模板及優化

KMP模板及優化

博主連結

KMP模板

#include<bits/stdc++.h>
using namespace std;
const int maxn=10001;
int next[maxn];
char s[maxn];
char p[maxn];
int cnt=0;
void prefix_next(int n){
	next[0]=0;
	int len=0;
	int i=1;
	while(i<n){
		if(p[i]==p[len]){
			len++;
			next[i]=len;
		}
		else {
			if(len>0){
				len=next[len-1]
; } else{ next[i++]=len; } } } return; } void move_next(int n){ for(int i=n-1;i>0;i--){ next[i]=next[i-1]; } next[0]=-1; return; } void kmp_search(){ int n=strlen(p); int m=strlen(s); prefix_next(n); move_next(n); int i=0; int j=0; while(i<m){ if(s[i]==p[j]&&
j==n-1){ printf("No.%d-->%d\n",++cnt,i-j); j=next[j]; } if(s[i]==p[j]){ i++; j++; } else{ j=next[j]; if(j==-1){ i++;j++; } } } if(cnt==0)cout<<"NO FOUD"<<endl; return; } int main(){ cin>>s; cin>>p; kmp_search(); }

KMP優化模板

#include<iostream>
#include<stdio.h> #include<string.h> using namespace std; char s[1000005],t[200000]; int slen,tlen; int nex[200000];//nex陣列大小和短串一致 int ans,a,b,c,d,n,m; inline void get_nex() { int j=-1;//j初始化為-1 for (int i=0;i<tlen;i++){ while (t[i]!=t[j+1] && j!=-1)//如果下一個不同,那麼j就變成next[j],注意next[j]是小於j的,無論j取任何值 j=nex[j];//往前回溯 if (t[i]==t[j+1] && i!=0) j++;//如果相同,j++ nex[i]=j;//這個是把算的j的值(就是相同的最大字首和最大字尾長)賦給next[i] } } inline void kmp() { int j=-1; for (int i=0;i<slen;i++){ while (s[i]!=t[j+1] && j!=-1) j=nex[j]; if (s[i]==t[j+1]) j++; if (j==tlen-1) ans++,j=nex[j]; } } int main() { scanf("%d",&n); for (int i=1;i<=n;i++){ ans=0; scanf("%s %s",t,s); slen=strlen(s); tlen=strlen(t);//這兩個長度應該設為全域性變數最開始時求出,不能用一次求一次 get_nex(); kmp(); printf("%d\n",ans); } }