kmp与扩展kmp模板

本文深入讲解了KMP算法的原理及应用,包括基本的KMP算法实现和扩展KMP算法,用于字符串匹配和查找最长公共前缀。通过具体的代码示例,详细解释了如何生成next数组和extend数组,以及它们在算法中的作用。
摘要由CSDN通过智能技术生成

kmp

复制代码
 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 
 6 using namespace std;
 7 
 8 struct KMP{
 9     char y[1010];//主串
10     char x[1010];//模式串
11     int n,m;
12     int next[1010];
13 
14     int init(){
15         scanf("%s%s",y,x);
16         n=strlen(y);
17         m=strlen(x);
18         kmp_pre();
19         //prekmp();
20         return 1;
21     }
22 
23     void kmp_pre(){//生成next数组
24         int i,j;
25         j=next[0]=-1;
26         i=0;
27         while(i<m){
28             while(-1!=j&&x[i]!=x[j])j=next[j];
29             next[++i]=++j;
30         }
31     }
32 
33     /*void prekmp(){
34         int i,j;
35         j=next[0]=-1;
36         i=0;
37         while(i<m){
38             while(-1!=j&&x[i]!=x[j])j=next[j];
39             if(x[++i]==x[++j])next[i]=next[j];
40             else next[i]=j;
41         }
42     }*/
43 
44     int kmp_count(){
45         int i,j;
46         int ans;
47         i=j=ans=0;
48         while(i<n){
49             while(-1!=j&&y[i]!=x[j])j=next[j];
50             i++;j++;
51             if(j>=m){
52                 ans++;
53                 j=next[j];
54             }
55         }
56         return ans;
57     }
58 };
59 
60 int main()
61 {
62     KMP a;
63     while(a.init())
64         printf("%d\n",a.kmp_count());
65     return 0;
66 }
67 //如果n%(n-next[n])==0,则存在重复连续子串,长度为n-next[n]。
复制代码

扩展kmp

复制代码
 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 
 6 using namespace std;
 7 
 8 struct KZ_KMP{//求最长公共前缀
 9     char y[1010];//主串
10     char x[1010];//模式串
11     int n,m;
12     int next[1010];//next[i]:x[i...m-1]与x[0...m-1]的最长公共前缀
13     int extend[1010];//extend[i]:y[i...n-1]与x[0...m-1]的最长公共前缀
14 
15     int init(){
16         scanf("%s%s",y,x);
17         n=strlen(y);
18         m=strlen(x);
19         pre_EKMP();
20         EKMP();
21         return 1;
22     }
23 
24     void pre_EKMP(){
25         next[0]=m;
26         int j=0;
27         while(j+1<m&&x[j]==x[j+1])j++;
28         next[1]=j;
29         int  k=1;
30         for(int i=2;i<m;i++){
31             int p=next[k]+k-1;
32             int L=next[i-k];
33             if(i+L<p+1)next[i]=L;
34             else{
35                 j=max(0,p-i+1);
36                 while(i+j<m&&x[i+j]==x[j])j++;
37                 next[i]=j;
38                 k=i;
39             }
40         }
41     }
42 
43     void EKMP(){
44         int j=0;
45         while(j<n&&j<m&&x[j]==y[j])j++;
46         extend[0]=j;
47         int k=0;
48         for(int i=1;i<n;i++){
49             int p=extend[k]+k-1;
50             int L=next[i-k];
51             if(i+L<p+1)extend[i]=L;
52             else{
53                 j=max(0,p-i+1);
54                 while(i+j<n&&j<m&&y[i+j]==x[j])j++;
55                 extend[i]=j;
56                 k=i;
57             }
58         }
59         //printf("%d ",extend[0]);
60     }
61 };
62 
63 int main()
64 {
65     KZ_KMP a;
66     while(a.init()){
67     }
68     return 0;
69 }
复制代码

转载于:https://www.cnblogs.com/DWVictor/p/10327407.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值