P3375 【模板】KMP字符串匹配

题目链接:https://www.luogu.com.cn/problem/P3375

方法一:BF片段

 1 int BF(string s,string t,int pos){
 2     int i=pos,j=0,sum=0;
 3     int slen=s.length();
 4     int tlen=t.length();
 5     while(i<slen&&j<tlen){
 6         sum++;
 7         if(s[i]==t[j])//如果相等,则继续比较后面的字符
 8             i++,j++;
 9         else{
10             i=i-j+1; //i回退到上一轮开始比较的下一个字符
11             j=0;  //j回退到第1个字符
12         }
13     }
14     cout<<"一共比较了"<<sum<<""<<endl;
15     if(j>=tlen) // 匹配成功
16         return i-tlen+1;
17     else
18         return 0;
19 }

 

方法二:KMP

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxl=1e6+10;
 7 char s[maxl], t[maxl];
 8 int slen, tlen, nxt[maxl];
 9 void get_nxt(){//求模式串t的nxt函数 
10     int j=0, k=-1;//k=-1代表模式串回到初始初始位置 
11     nxt[0]=-1;
12     while(j<=tlen){
13         if(k==-1 || t[k]==t[j]){
14             nxt[++j]=++k;
15         }
16         else
17             k=nxt[k];
18     }
19     //testcode
20     //for(int i=0; i<=tlen; i++)printf("%d ", nxt[i]);
21 }
22 void kmp(){
23     get_nxt();
24     int i=0, j=0;
25     int cnt=0;//比较次数 
26     while(i<slen){//只要判断匹配串的长度即可 
27         cnt++;
28         if(j==-1 || s[i]==t[j]) {
29             i++, j++;
30             if(j>=tlen)//匹配成功
31                 printf("%d\n", i-tlen+1); 
32         }
33         else
34             j=nxt[j];
35     }
36 }
37 int main()
38 {
39     scanf("%s%s", s, t);
40     slen=strlen(s);  tlen=strlen(t);
41     t[tlen]='e';//多加一个变成tlen+1长度是为了,因为初始值为-1,得出tlen长度的nxt值 
42     kmp();
43     for(int i=1; i<=tlen; i++)printf("%d ", nxt[i]);
44 
45     return 0;
46 }

 

posted @ 2022-05-03 16:39  TFLSNOI  阅读(61)  评论(0)    收藏  举报