首页 > 其他分享 >AC自动机

AC自动机

时间:2022-10-27 19:24:08浏览次数:72  
标签:rt AC int ac son fail 自动机 指针

\(Kmp\)与\(Trie\)的优美结合,相当于在\(Trie\)上跑\(Kmp\)。

一个重要定义:\(Fail\)指针(失配指针),指向其他路径上与该字母相同的节点。当前路径的模式串的后缀与\(fail\)指针指向的模式串前缀相同(与\(kmp\)类似)。
\(Fail\)指针的作用:在对于一个文本串匹配多个模式串时,如果当前模式串已经结束或失配,一般情况下我们需要回溯到根节点再换路递归,但是可以用\(fail\)直接跳到下一条路径,而且这条路径是紧接上一条的(并且与文本串对应),这样省去了回溯。因为对于\(fail\)指向的那一条路径的前缀已经在这时(被当前模式串)走过了,我们不需再走一遍重复路径。
在跳\(fail\)指针时不断统计答案,就可以遍历到以该字母为结尾的所有模式串。
构造\(Fail\)指针:对于每一层的\(fail\)指针,我们都需要用到上一层的\(fail\)状态,所以采取\(bfs\),分层构造,对于第一层的\(fail\),都指向\(0\)号根节点(它只是一个虚点)。对于一个节点x,它的\(fail\)只需要指向它父亲的\(fail\)的同字符儿子。

struct Trie
{
    int kid[26];//26个字母
    int fail;//失配指针
    int end;//以该节点结尾的单词数量
    #define son ac[rt].kid[i]
}; Trie ac[Z << 2];
int tot = 0;
inline void insert(char s[], int len)
{
    int rt = 0;
    for (re t = 1; t <= len; t++)
    {
        int i = s[t] - 'a';
        if (!son) son = ++tot;//新建一个节点
        rt = son;//进入下一层
    }
    ac[rt].end++;
}
void getfail()
{
    ac[0].fail = 0;//fail结束边界
    queue <int> q;
    int rt = 0;
    for (re i = 0; i < 26; i++)
        if (son)
        {
            ac[son].fail = 0;//初始化失配指针
            q.push(son);
        }
    while (!q.empty())
    {
        rt = q.front(); q.pop();
        for (re i = 0; i < 26; i++)
        {
            if (son)
            {
                ac[son].fail = ac[ac[rt].fail].kid[i];//扩展后缀
                q.push(son);
            }
            else son = ac[ac[rt].fail].kid[i];//保证字符串能沿着路径走完
        }
    }
}
inline int match(char s[], int len)
{
    int rt = 0, ans = 0;
    for (re t = 1; t <= len; t++)
    {
        rt = ac[rt].kid[s[t] - 'a'];//向下走一层
        for (re j = rt; j && ac[j].end != -1; j = ac[j].fail)
            ans += ac[j].end, ac[j].end = -1;//j不断跳fail直到完全失配
    }
    return ans;
}

标签:rt,AC,int,ac,son,fail,自动机,指针
From: https://www.cnblogs.com/sandom/p/16833415.html

相关文章

  • FaceBook营销软使用技巧,如何翻译聊天记录,设置快捷话术
    下面我来介绍下FaceBook营销软件客服台具备的功能常用话术:添加常用的话术,将话术内容快速发送至联系人聊天窗口,很大程度提升了与好友聊天的便捷度。导入其他子账号话术:软件会......
  • Mac配置Ruby环境和安装CocoaPods
    重装命令行工具$sudorm-rf/Library/Developer/CommandLineTools$sudoxcode-select--install安装RVMRVM是一个命令行工具,可以提供一个便捷的多版本Ruby环境......
  • EhCache分布式缓存
    1.什么是EhCacheEhCache是一个比较成熟的Java缓存框架,最早从hibernate发展而来,是进程中的缓存系统,它提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管......
  • ac 3完全背包问题
    #include<bits/stdc++.h>usingnamespacestd;constintN=1010;intn,m;intv[N],w[N];intf[N];intmain(){cin>>n>>m;for(inti=1;i<=......
  • HCIE-DATACOM进行中
    在苦思冥想中在8月份准备备考HCIE-DATACOM,后期也会跟大家更新HCIE-datacom的知识点目前状况是笔试在9月31号通过了,机试会在12月26开始考试!......
  • 记录一下阿里云ACK的nodeport Local Cluster
    背景:很久很近以前(恩200多天前了),创建了一个服务应用,使用了nodeport的方式对外暴露服务,划重点--控制台创建的网络服务:过程就是这样的......一直相安无事。但是不明所以今天......
  • Codeforces Round #619 (Motarack's Birthday)
    题面DarkisgoingtoattendMotarack’sbirthday.DarkdecidedthatthegiftheisgoingtogivetoMotarackisanarrayaofnnon-negativeintegers.Darkcr......
  • ERROR 1694 (HY000): Cannot modify @@session.sql_log_bin inside a transaction
    MySQL执行sys.diagnostics存储过程如下报错root@localhost[(none)]>callsys.diagnostics(null,null,'current');+-------------------+|summary|+-----......
  • nacos——02
    实例注册——服务端处理RequestHandlernacos所有request处理的父类,子类需要实现handle方法packagecom.alibaba.nacos.core.remote;/***Nacosbasedrequesthandler.**......
  • ACWing 3549 -- dp&&滚动数组
    题目描述最长非递减子序列思路Reference代码......