AC自动机 算法详解(图解)及模板

AC自动机 算法详解(图解)及模板ac 自动机 就是在 tire 树的基础上 增加一个 fail 指针 如果当前点匹配失败 则将指针转移到 fail 指针指向的地方 这样就不用回溯 而可以路匹配下去了 当前模式串后缀和 fail 指针指向的模式串部分前缀相同 如 abce 和 bcd 我们找到 c 发现下一个要找的不是 e 就跳到 bcd 中的 c 处 看看此处的下一个字符 d 是不是应该找的那一个




转载注明出自bestsort.cn,谢谢合作









大家回复请去bestsort.cn回复吧,CSDN我每次都不知道你们回复的楼层在哪…点击查看评论它都不带自动跳转的QAQ







AC自动机 算法详解(图解)及模板


喜闻乐见模板系列

 #include  
         #include  
         #include  
         #include  
         #include  
         #include  
         #include  
         #include  
         using namespace std; typedef long long ll; const int maxn = 2*1e6+9; int trie[maxn][26]; //字典树 int cntword[maxn]; //记录该单词出现次数 int fail[maxn]; //失败时的回溯指针 int cnt = 0; void insertWords(string s){ 
        int root = 0; for(int i=0;i<s.size();i++){ 
        int next = s[i] - 'a'; if(!trie[root][next]) trie[root][next] = ++cnt; root = trie[root][next]; } cntword[root]++; //当前节点单词数+1 } void getFail(){ 
        queue <int>q; for(int i=0;i<26;i++){ 
        //将第二层所有出现了的字母扔进队列 if(trie[0][i]){ 
        fail[trie[0][i]] = 0; q.push(trie[0][i]); } } //fail[now] ->当前节点now的失败指针指向的地方 tire[now][i] -> 下一个字母为i+'a'的节点的下标为tire[now][i] while(!q.empty()){ 
        int now = q.front(); q.pop(); for(int i=0;i<26;i++){ 
        //查询26个字母 if(trie[now][i]){ 
        //如果有这个子节点为字母i+'a',则 //让这个节点的失败指针指向(((他父亲节点)的失败指针所指向的那个节点)的下一个节点) //有点绕,为了方便理解特意加了括号 fail[trie[now][i]] = trie[fail[now]][i]; q.push(trie[now][i]); } else//否则就让当前节点的这个子节点 //指向当前节点fail指针的这个子节点 trie[now][i] = trie[fail[now]][i]; } } } int query(string s){ 
        int now = 0,ans = 0; for(int i=0;i<s.size();i++){ 
        //遍历文本串 now = trie[now][s[i]-'a']; //从s[i]点开始寻找 for(int j=now;j && cntword[j]!=-1;j=fail[j]){ 
        //一直向下寻找,直到匹配失败(失败指针指向根或者当前节点已找过). ans += cntword[j]; cntword[j] = -1; //将遍历国后的节点标记,防止重复计算 } } return ans; } int main() { 
        int n; string s; cin >> n; for(int i=0;i<n;i++){ 
        cin >> s ; insertWords(s); } fail[0] = 0; getFail(); cin >> s ; cout << query(s) << endl; return 0; } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/199102.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午1:51
下一篇 2026年3月26日 下午1:51


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号