AC自动机——无法自动AC的数据结构,trie树与字符串的结合,用于以多组数据匹配一种数据;
int tr[N*M][26],idx;
int ne[N*M];
int cnt[N*M];
int q[N*M];
tr数组是trie树数组,ne数组是kmp的next数组,cnt数组则记录trie树中对应位置的字符串出现了多少次,
q数组为队列
void insert(string s)
{
int p=0;
for(int i=0;i<s.size();i++)
{
int t=s[i]-'a';
if(!tr[p][t]) tr[p][t]=++idx;
p=tr[p][t];
}
cnt[p]++;
}
建树过程与trie树相同
void build()//一层层bfs构建ne数组
{
int hh=0,tt=-1;
for(int i=0;i<26;i++)
if(tr[0][i]) q[++tt]=tr[0][i];
while(hh<=tt)
{
int t=q[hh++];
for(int i=0;i<26;i++)
{
int c=tr[t][i];
if(!c) tr[t][i]=tr[ne[t]][i];//把不存在的点连起来使得求ne数组不再需要一层层往上循环
else
{
ne[c]=tr[ne[t]][i];
q[++tt]=c;
}
}
}
}
建立ne数组的过程,为一层一层bfs,这里优化了一下成为了trie图
for(int i=0,j=0;i<s1.size();i++)
{
int t=s1[i]-'a';
j=tr[j][t];
int p=j;
while(p)
{
res+=cnt[p]; cnt[p]=0;p=ne[p];
}
}
匹配的时候注意回溯,否则可能会漏,这里其实还可以加一个st数组防止重复匹配