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

    假设手里有N个串,和原文进行匹配,如果跑KMP,得把原文跑N次,实在是太费时间了。AC自动机借助于Trie的压缩功能,将多个串压成一个“树”,用这个树进行KMP,这就是贝尔实验室发明的AC自动机。
    AC自动机主要有三个操作;insert,getfail,print,find。
    insert的操作和Trie一样。
    void Insert(string str,int v)
    {
        int u=0,c;
        for(int i=0;i<str.size();i++)
        {
            c=str[i]-'a';
            if(!ch[u][c])
            {
                val[sz]=0;
                ch[u][c]=sz++;
            }
            u=ch[u][c];
        }
        val[u]=v;
    }
    insert的操作

    getfail采用BFS,逐个检查,记录后缀链接last数组

    void GetFail()
    {
        queue<int> Q;
        f[0]=0;
        for(int c=0;c<26;c++)
        {
            int u=ch[0][c];
            if(u)
            {
                f[u]=last[u]=0;
                Q.push(u);
            }
        }
        while(!Q.empty())
        {
            int r=Q.front();Q.pop();
            for(int c=0;c<26;c++)
            {
                int u=ch[r][c];
                if(!u)
                {
                    ch[r][c]=ch[f[r]][c];
                    continue;
                }
                Q.push(u);
                int v=f[r];
                while(v&&!ch[v][c]) v=f[v];
                f[u]=ch[v][c];
                last[u]=val[f[u]]?f[u]:last[f[u]];
            }
        }
    }
    getfail的操作

    find对应的是原文

    void Find(string str)
    {
        int j=0,c;
        for(int i=0;i<str.size();i++)
        {
            c=str[i]-'a';
            j=ch[j][c];
            if(val[j]) print(j);
            else if(last[j]) print(last[j]);
        }
    }
    find的操作

    print表示在确定一个串后的操作

    void print(int j)
    {
        if(j)
        {
            cnt[val[j]]++;
            print(last[j]);
        }
    }
    print的操作

    整个自动机中,最重要的是后缀链接last数组的使用,对于一个单词的尾结点,可能对应多个串,需要沿着往回走,看看有没有串了。

    @练习题

    HDU 2222

    HDU 2896

    HDU 3065


  • 相关阅读:
    2017免费获取正版win10的方法
    Apache <Directory>… </Directory>配置
    针对left join以及limit的两条优化小技巧
    win10打印机突然无法启动
    mysql中的分组统计函数及其用法实例
    程序猿的日常生活-雨中
    java中的反射
    mysql中的截取函数及其实例
    集合与数组
    方法重写
  • 原文地址:https://www.cnblogs.com/neopenx/p/4004407.html
Copyright © 2011-2022 走看看