zoukankan      html  css  js  c++  java
  • KMP & AC自动机

    KMP

    void kmp(char t[],char p[])
    {
        int n=strlen(t),m=strlen(p);
        int *f=new int[m];
        f[0]=f[1]=0;
        for(int i=1;i<m;++i)
        {
            int j=f[i];
            while(j&&p[i]!=p[j])j=f[j];
            f[i+1]=p[j]==p[i]?j+1:0;
        }
        for(int i=0,j=0;i<n;++i)
        {
            while(j&&t[i]!=p[j])j=f[j];
            if(t[i]==p[j])j++;
            if(j==m)printf("%d
    ",i-m+1);
        }
        delete[] f;
    }
    

    Aho-Corasick automa

    Trie + fail[] & last[] + matching
    int fail[int i]失配函数,注意i和fail[i]结点对应的字母相同;f[0]=0,f[ch[0][u]]=0。
    int last[int i]沿失配函数往回走遇到的第一个单词结点。(可选)

    输出所有与前i位的后缀匹配的单词的val值
    可能有错

    const int maxn=1e6+5;
    struct trie
    {
        int ch[500010][26],val[maxn],fail[maxn],last[maxn];
        int sz;
        trie(){sz=0;ms(ch[0],0);}
        void Insert(char s[],int v)
        {
            int u;for(u=0;*s;++s){if(!ch[u][*s-'a']){ch[u][*s-'a']=++sz;ms(ch[sz],0);}u=ch[u][*s-'a'];val[u]=0;}
            val[u]=v;
        }
        void GetFailLast()
        {
            queue<int> q;while(!q.empty())q.pop();q.push(0);fail[0]=0;for(int i=0;i<26;++i)fail[ch[0][i]]=0;
            while(!q.empty())
            {
                int u=q.front();q.pop();
                for(int i=0;i<26;++i)
                {
                    int v=ch[u][i],t=fail[u];;if(!v)continue;
                    q.push(v);
                    while(t&&!ch[t][i])t=fail[t];
                    fail[v]=ch[t][i];last[v]=val[fail[v]]?fail[u]:last[fail[v]];
                }
            }
        }
        void Query(char s[])
        {
            for(int u=0,i=0;*s;s++,i++){while(u&&!ch[u][*s-'a'])u=fail[u];u=ch[u][*s-'a'];int tmp=val[u]?u:last[u];while(tmp)printf("%d %d
    ",i,val[tmp]),tmp=last[tmp];}
        }
    }T;
    

    另一版本

    • ch[][]给出了自动机状态转移图的完整邻接表
    • 加上根结点一共sz个结点,其中根结点标号为0,其余分别为1,...,sz-1
    • 查询时,每一步都需要沿fail[]往回检查
    • -1表示结点不存在(用memset初始化是可行的。memset可以初始化0和-1)
    const int sigma_size=26,max_node=100;
    struct Trie
    {
        int ch[max_node][sigma_size],val[max_node],fail[max_node],sz;
        int newnode(){memset(ch[sz],-1,sizeof ch[sz]);val[sz]=0;return sz++;}
        void init(){sz=0;newnode();}
        void insert(char s[],int v)
        {
            int u;for(u=0;*s;++s){if(ch[u][*s-'a']==-1)ch[u][*s-'a']=newnode();u=ch[u][*s-'a'];}
            val[u]=v;
        }
        void build()
        {
            queue<int>q;
            for(int i=0;i<sigma_size;++i)
            {
                int &v=ch[0][i];
                if(v==-1)v=0;
                else {fail[v]=0;q.push(v);}
            }
            while(!q.empty())
            {
                int u=q.front();q.pop();
                for(int i=0;i<sigma_size;++i)
                {
                    int &v=ch[u][i];
                    if(v==-1)v=ch[fail[u]][i];
                    else{fail[v]=ch[fail[u]][i];q.push(v);}
                }
            }
        }
        void query(char s[])
        {
            for(int u=0,t,cnt=0;*s;++s,++cnt)
            {
                t=u=ch[u][*s-'a'];
                while(t){if(val[t])printf("%d %d
    ",cnt,val[t]);t=fail[t];}
            }
        }
    }T;
    
  • 相关阅读:
    如何使用jetty
    windows安装TortoiseGit详细使用教程【基础篇】
    shiro实现APP、web统一登录认证和权限管理
    Eclipse上安装GIT插件EGit及使用
    RPC之——HTTP协议栈
    Spring Boot构建RESTful API与单元测试
    Spring 之注解事务 @Transactional
    浅析Java中的final关键字
    String中intern的方法
    MySQL索引的查看创建和删除
  • 原文地址:https://www.cnblogs.com/maoruimas/p/9579557.html
Copyright © 2011-2022 走看看