zoukankan      html  css  js  c++  java
  • 【模板】KMP算法,AC自动机

    KMP算法:洛谷3375

       根据我的理解,把next数组改成了fail数组。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1000010;
     4 char s1[N],s2[N];
     5 int l1,l2,fail[N];
     6 void getfail(){
     7     fail[0]=fail[1]=0;
     8     int k;
     9     for(int i=1;i<l2;i++){
    10         k=fail[i];
    11         while(k&&s2[i]!=s2[k]) k=fail[k];
    12         fail[i+1]=s2[k]==s2[i]?k+1:0;
    13     }
    14     return;
    15 }
    16 void find(){
    17     int p2=0;
    18     for(int i=0;i<l1;i++){
    19         while(s1[i]!=s2[p2]&&p2) p2=fail[p2];
    20         if(s1[i]==s2[p2]) p2++;
    21         if(p2==l2) printf("%d
    ",i-l2+2);
    22     }
    23 }
    24 int main(){
    25     scanf("%s%s",&s1,&s2);
    26     l1=strlen(s1),l2=strlen(s2);
    27     getfail();find();
    28     for(int i=1;i<=l2;i++) printf("%d ",fail[i]);
    29     return 0;
    30 }

    AC自动机:洛谷3808

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1000010;
     4 int n,ans;
     5 char ss[N];
     6 int ch[N][26],v[N],fail[N],last[N],tot;
     7 inline void insert(char *s){
     8     int l=strlen(s),now=0;
     9     for(int i=0;i<l;i++){
    10         int nxt=s[i]-'a';
    11         if(!ch[now][nxt]) ch[now][nxt]=++tot;
    12         now=ch[now][nxt];
    13     }
    14     v[now]++;
    15     return;
    16 }
    17 inline void build(){
    18     queue<int>q;
    19     for(int i=0;i<26;i++) if(ch[0][i]) q.push(ch[0][i]);
    20     int x;
    21     while(!q.empty()){
    22         x=q.front();q.pop();
    23         for(int i=0;i<26;i++)if(ch[x][i]){
    24             int j=fail[x];
    25             while(j&&!ch[j][i]) j=fail[j];
    26             fail[ch[x][i]]=ch[j][i];
    27             last[ch[x][i]]=v[ch[j][i]]?ch[j][i]:last[ch[j][i]];
    28             q.push(ch[x][i]);
    29         }
    30     }
    31     return;
    32 }
    33 inline void find(char* s){
    34     int l=strlen(s),now=0;
    35     for(int i=0;i<l;i++){
    36         int c=s[i]-'a';
    37         while(now&&!ch[now][c]) now=fail[now];
    38         now=ch[now][c];
    39         int j=now;
    40         while(j) ans+=v[j],v[j]=0,j=last[j];
    41     }
    42     return;
    43 }
    44 int main(){
    45     scanf("%d",&n);
    46     for(int i=1;i<=n;i++){scanf("%s",ss);insert(ss);}
    47     scanf("%s",ss);
    48     build();
    49     find(ss);
    50     printf("%d",ans);
    51     return 0;
    52 }

     upd:

      2018.3.14 重打了AC自动机的模板 (原来的好丑。。)

  • 相关阅读:
    css介绍与引入
    [K/3Cloud] 单据转换插件执行顺序
    [K/3Cloud] 如何设置设置单据分录中的整列的精度
    [K/3Cloud] 单据新增、复制、新增行、复制行的过程
    [K/3Cloud] 代码中设置某个字段必录
    [K/3Cloud] 创建一个业务单据表单插件
    [K/3Cloud] 创建一个单据转换插件
    [K/3Cloud] 创建一个操作校验器
    [K3Cloud] QueryService使用注意事项
    [K/3Cloud] 树形单据体的应用说明
  • 原文地址:https://www.cnblogs.com/mycups/p/8564440.html
Copyright © 2011-2022 走看看