kmp

kmp 模版

传入 主串text,匹配串pat,传出text上数组下标开始为什么时能匹配pat。 如 asdvs sd 传出1。
int nxt[MAXN]; //nxt[i] 指下标为i的字符的前面最多nxt[i]个字符与开始的nxt[i]个字符相同 ;

int nxt[MAXN];
char text[MAXN] ,pat[MAXN];
void get_nxt(char *pat,int lenp){
int i = 0, j = -1;
nxt[0] = -1;
while(i < lenp){
if(j == -1 || pat[i] == pat[j]){
i ++; j ++;
nxt[i] = j;
}
else j = nxt[j];
}
}
int KMP(char *text,char *pat){
int lent = strlen(text),lenp = strlen(pat);
get_nxt(pat,lenp);
int i = 0, j = 0;
while(i < lent && j < lenp){
if(j == -1 || text[i] == pat[j]){
i ++; j ++;
}
else j = nxt[j];
}
if(j >= lenp) return i - lenp;
else return -1;
}

int main(){
scanf("%s%s", text, pat);
printf("%d\n", KMP(text,pat));
return 0;
}


应用:

1:求子串 pat[0```i] (及pat[]的前缀) 在主串 text[] 出现的次数

模版:

 1 num[i] 中返回的是子串前缀长为i 在主串出现的次数
2
3 #include<iostream>
4 #include<cstdio>
5 #include<vector>
6 #include<string.h>
7 #include<cmath>
8 #include<queue>
9 #include<set>
10 #include<cstdlib>
11 #include<algorithm>
12 #include <iomanip>
13 #include <bitset>
14 using namespace std;
15 #define LL long long
16 const int MAX = 200010;
17 const int INF=100000000;
18 LL nxt[MAX], num[MAX];
19 char text[MAX] ,pat[MAX];
20
21 void get_nxt(char *pat,LL lenp){
22 LL i = 0, j = -1;
23 nxt[0] = -1;
24 while(i <=lenp){
25 if(j == -1 || pat[i] == pat[j]){
26 i ++; j ++;
27 nxt[i] = j;
28 }
29 else j = nxt[j];
30 }
31 }
32 void KMP(char *text,char *pat){
33 LL lent = strlen(text),lenp = strlen(pat);
34 get_nxt(pat,lenp);
35 LL i = 0, j = 0;
36 while(i < lent){
37 if(j == -1 || text[i] == pat[j]){
38 if(j!=-1) num[j+1]++;
39 j ++; i ++;
40 }
41 else j = nxt[j];
42 }
43 }
44
45 int main(){
46 scanf("%s%s", text, pat);
47 memset(num,0,sizeof(num));
48
49 LL lenp=strlen(pat),lent=strlen(text);
50 KMP(text,pat);
51 for(LL i=lenp;i>0;i--) {
52 if(nxt[i]!=-1) num[nxt[i]]+=num[i];
53 }
54
55 return 0;
56 }



zoj 3587

View Code
 1 #include<iostream>
2 #include<cstdio>
3 #include<vector>
4 #include<string.h>
5 #include<cmath>
6 #include<queue>
7 #include<set>
8 #include<cstdlib>
9 #include<algorithm>
10 #include <iomanip>
11 #include <bitset>
12 using namespace std;
13 #define LL long long
14 const int MAX = 200010;
15 const int INF=100000000;
16 LL nxt[MAX];
17 char text[MAX] ,pat[MAX];
18 LL a[MAX],b[MAX];
19 void get_nxt(char *pat,LL lenp){
20 LL i = 0, j = -1;
21 nxt[0] = -1;
22 while(i <=lenp){
23 if(j == -1 || pat[i] == pat[j]){
24 i ++; j ++;
25 nxt[i] = j;
26 }
27 else j = nxt[j];
28 }
29 }
30 void KMP(char *text,char *pat,bool flag){
31 LL lent = strlen(text),lenp = strlen(pat);
32 get_nxt(pat,lenp);
33 LL i = 0, j = 0;
34 while(i < lent){
35 if(j == -1 || text[i] == pat[j]){
36 if(!flag&&j!=-1) a[j+1]++;
37 else if(flag&&j!=-1) b[j+1]++;
38 j ++; i ++;
39 }
40 else j = nxt[j];
41 }
42 }
43
44 int main(){
45 LL T;
46 scanf("%lld",&T);
47 while(T--){
48 scanf("%s%s", text, pat);
49 memset(a,0,sizeof(a));
50 memset(b,0,sizeof(b));
51
52 LL lenp=strlen(pat),lent=strlen(text);
53 KMP(text,pat,0);
54 for(LL i=lenp;i>0;i--) {
55 if(nxt[i]!=-1) a[nxt[i]]+=a[i];
56 }
57
58 for(LL i=0;i<lent/2;i++) swap(text[i],text[lent-i-1]);
59 for(LL i=0;i<lenp/2;i++) swap(pat[i],pat[lenp-i-1]);
60 KMP(text,pat,1);
61 for(LL i=lenp;i>0;i--) {
62 if(nxt[i]!=-1) b[nxt[i]]+=b[i];
63 }
64
65 LL ans=0;
66 for(LL i=1;i<lenp;i++) ans+=a[i]*b[lenp-i];
67 printf("%lld\n",ans);
68 }
69 return 0;
70 }



posted @ 2012-03-11 21:06  HaoHua_Lee  阅读(406)  评论(0编辑  收藏  举报