zoukankan      html  css  js  c++  java
  • kmp与扩展kmp模板

    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
    ",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 }
    复制代码
  • 相关阅读:
    es6之proxy和reflect
    es6之数据结构
    es6之Symbol
    es6之函数扩展与对象扩展
    es6之数组方法
    es6的解构赋值
    使用npm uninstall卸载express无效
    移动端UC /QQ 浏览器的部分私有Meta 属性
    js 判断移动设备、pc端、android、iPhone、是否为微信、微博、qq空间
    c# 获取文件本身的哈希值
  • 原文地址:https://www.cnblogs.com/DWVictor/p/10327407.html
Copyright © 2011-2022 走看看