AC自动机:
功能:
可以实现对多个模式串的匹配
原理
借用KMP的思想,我们用一个fail数组记录失配的字符串,用来表示最长的可以用来表示有效前缀的后缀
图解
黄色线代表回溯的线段,也就是fail数组,fail必须要连接到层数比他高,且相同的字符上
绿色线代表将字符串来匹配模式串的过程
步骤
- 先建立一个trie
void insert(char *a)
{
int u = 0;
for(int i=0;a[i];i++)
{
int ch = a[i]-'A';
if(!go[u][ch])go[u][ch]=++Icnt;
u = go[u][ch];
}
val[u]++;
}
- 在进行make_fail操作
//模板一
void make_fail()
{
queue<int>Q;
for(int i=0;i<26;i++)if(go[0][i])Q.push(go[0][i]);
while(Q.size())
{
int u = Q.front();Q.pop();
val[u]+=val[fail[u]];//我们这一行可以用来累加总共匹配的模式串
for(int i=0;i<26;i++)
if(go[u][i])fail[go[u][i]] = go[fail[u]][i],Q.push(go[u][i]);
else go[u][i]=go[fail[u]][i];
}
}
3.query
int tmp = 0;
for(int i=0;s[i];i++){
tmp = go[tmp][s[i]-'a'];
int p = tmp;
// while(p)
// {
// ans[id[p]]+=val[p];
// p = fail[p];
// }
如果val没有累计,或者是求取各个字符串的匹配情况,就要使用上面的回溯的操作
ans+=val[tmp];
}
LAST: 题型,+dp / 多串匹配
(持续修补中)