AC自动机
- 初始化失配指针:
- 根节点的失配指针指向自身。
- 根节点的所有子节点的失配指针指向根节点。
- 对于其他节点,使用广度优先搜索(BFS)的方式逐层计算失配指针。对于一个节点u,假设其父节点为p,且从p到u的边对应的字符为c,则找到p的失配指针所指向的节点q,如果q有字符c对应的子节点v,则将u的失配指针指向v;如果没有,则继续沿着q的失配指针向上查找,直到找到合适的节点或者到达根节点。
- 匹配过程
- 从文本的第一个字符开始,从根节点开始在 AC 自动机上进行匹配。对于文本中的每个字符c:
如果当前节点有字符c对应的子节点,则移动到该子节点。
如果没有,则沿着当前节点的失配指针向上跳转,直到找到有字符c对应的子节点或者到达根节点。
每到达一个节点,检查该节点及其失配指针所指向的节点是否为某个模式串的结尾,如果是,则记录匹配信息。
- 从文本的第一个字符开始,从根节点开始在 AC 自动机上进行匹配。对于文本中的每个字符c:
板子
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int ch[N][27],cnt[N];
int idx;
void insert(string s)
{
int l=s.size();
int p=0;
for(int i=0;i<l;i++)
{
int x=s[i]-'a'+1;
if(!ch[p][x])
ch[p][x]=++idx;
p=ch[p][x];
}
cnt[p]++;
}
int nxt[N];
void build()
{
queue<int> q;
for(int i=1;i<=26;i++)
{
if(ch[0][i])
q.push(ch[0][i]);
}
while(q.size())
{
int u=q.front();
q.pop();
for(int i=1;i<=26;i++)
{
int v=ch[u][i];
if(v)
nxt[v]=ch[nxt[u]][i],q.push(v);
else
ch[u][i]=ch[nxt[u]][i];
}
}
}
int query(string s)
{
int l=s.size();
int q=0;
int ans=0;
for(int i=0;i<l;i++)
{
int x=s[i]-'a'+1;
q=ch[q][x];
for(int j=q;j&&~cnt[j];j=nxt[j])
ans+=cnt[j],cnt[j]=-1;
}
return ans;
}
int main()
{
return 0;
}
本文来自博客园,作者:流氓兔LMT,转载请注明原文链接:https://www.cnblogs.com/-include-lmt/p/18742499

浙公网安备 33010602011771号