AC自动机??!!
Aho−Corasickautomaton
A
h
o
−
C
o
r
a
s
i
c
k
a
u
t
o
m
a
t
o
n
,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法。
什么是多模匹配?
就是给你一段
m
m
个句子的集合,给出
n
n
个单词,查看这些单词是否在中出现过;
AC自动机
学
AC
A
C
自动机之前,一定要看看
Tire树
T
i
r
e
树
和
KMP
K
M
P
。
因为
AC
A
C
自动机就相当于在
Tire
T
i
r
e
树上进行
KMP
K
M
P
,
AC自动机
A
C
自
动
机
有一种类似于
KMP
K
M
P
中
next[]
n
e
x
t
[
]
(不要写
next
n
e
x
t
,
c++11会CE
c
+
+
11
会
C
E
的….)的东西叫
fail
f
a
i
l
指针
fail
f
a
i
l
指针的功能:当你匹配失败的时候,你可以调到当前节点的
fail
f
a
i
l
指针所指的节点继续匹配.
所以:
AC自动机
A
C
自
动
机
的构建过程:
1.
1.
先把所给的串插入
Tire树
T
i
r
e
树
中
2.
2.
然后构建
fail
f
a
i
l
指针
3.
3.
就可以匹配了
下面就是一个已经构造完成
fail
f
a
i
l
指针的
AC自动机
A
C
自
动
机
红边为
fail
f
a
i
l
指针
fail
f
a
i
l
指针是怎样构建的呢?
用一句话简单的说就是,假如你要构建
now
n
o
w
节点的失配指针,假如它的父节点的失配指针指向的节点有一条和
now
n
o
w
节点到它父亲的边一样的边,那么
now
n
o
w
节点的失配指针指向这一条边所指向的节点.
代码
代码就比较好理解了,
inline void Build(char s[])
{
int l=strlen(s);
int now=0;
for(int i=0;i<l;++i)
{
if(AC[now].vis[s[i]-'a']==0)
AC[now].vis[s[i]-'a']=++cnt;
now=AC[now].vis[s[i]-'a'];
}
AC[now].end+=1;
}
void Get_fail()
{
queue<int> que;
for(int i=0;i<26;++i)
{
if(AC[0].vis[i]!=0)
{
AC[AC[0].vis[i]].fail=0;
que.push(AC[0].vis[i]);
}
}
while(!que.empty())
{
int u=que.front(); que.pop();
for(int i=0;i<26;++i)
{
if(AC[u].vis[i]!=0)
{
AC[AC[u].vis[i]].fail=AC[AC[u].fail].vis[i];
Q.push(AC[u].vis[i]);
}
else
AC[u].vis[i]=AC[AC[u].fail].vis[i];
}
}
}
如果有不正确的地方可以指出来,谢谢