此代码适用于Aho-Corasick算法,我已经从here
进行了审核我理解这个代码是否是push_links方法的块,但我没有得到相同方法的else部分的使用或要求。 更具体地,第一种方法用于构造trie。剩余的工作是通过第二种方法完成的,即将节点链接到它们最长的正确后缀,它们也是某种模式的前缀。这是由If块执行的,那么else部分的需要是什么。
请帮助我。
const int MAXN = 404, MOD = 1e9 + 7, sigma = 26;
int term[MAXN], len[MAXN], to[MAXN][sigma], link[MAXN], sz = 1;
// this method is for constructing trie
void add_str(string s)
{
// here cur denotes current node
int cur = 0;
// this for loop adds string to trie character by character
for(auto c: s)
{
if(!to[cur][c - 'a'])
{
//here two nodes or characters are linked using transition
//array "to"
to[cur][c - 'a'] = sz++;
len[to[cur][c - 'a']] = len[cur] + 1;
}
// for updating the current node
cur = to[cur][c - 'a'];
}
//for marking the leaf nodes or terminals
term[cur] = cur;
}
void push_links()
{
//here queue is used for breadth first search of the trie
int que[sz];
int st = 0, fi = 1;
//very first node is enqueued
que[0] = 0;
while(st < fi)
{
// here nodes in the queue are dequeued
int V = que[st++];
// link[] array contains the suffix links.
int U = link[V];
if(!term[V]) term[V] = term[U];
// here links for the other nodes are find out using assumption that the
// link for the parent node is defined
for(int c = 0; c < sigma; c++)
// this if condition ensures that transition is possible to the next node
// for input 'c'
if(to[V][c])
{
// for the possible transitions link to the reached node is assigned over
// here which is nothing but transition on input 'c' from the link of the
// current node
link[to[V][c]] = V ? to[U][c] : 0;
que[fi++] = to[V][c];
}
else
{
to[V][c] = to[U][c];
}
}
}
答案 0 :(得分:1)
IMO你不需要其他条件。如果没有孩子,那么它已经是一个链接或什么也没有。
答案 1 :(得分:0)
Aho-Corasick算法有一些变化。 基本算法假设如果当前节点( cur )的边缘超过符号( c ),则会通过后缀链接转到第一个边缘超过 c (你通过这个边缘移动)。 但是你在后缀链接上的方式是相同的(来自相同的 cur 和 c ),因为你在搜索时不会改变自动机。所以你可以缓存它(保存
的结果// start from node
while (parent of node doesn't have an edge over c) {
node = parent
}
// set trie position
node = to[node][c]
// go to next character
进入[node] [c]。所以下次你再也不会这样做了。并且它从自动机从非确定性状态转换为确定性状态机(推送后不必使用链接数组,只能使用到数组)。 / p>
此实施存在一些问题。首先,您可以获得您找到的字符串索引(您不能保存它)。此外,len阵列不会在任何地方使用。
对于
意味着,该算法只是使用&#34; link [to [V] [c]] = V?来检查当前节点链接中是否存在字符。至[U] [c]:0;&#34;。不应该在父母链接中验证吗?
是的,没关系,因为如果[U] [c]为0,那么来自所有链U-&gt; suffix_parent-&gt; suffix parent的suffix_parent的c没有边缘... - &GT; root = 0.所以你应该将[V] [c]设置为零。