有关AC自动机(简单版)的几点疑问
查看原帖
有关AC自动机(简单版)的几点疑问
434015
Calanosay楼主2021/4/1 13:35

关于fail数组的求解

void getFail(){
    queue <int>q;
    for(int i=0;i<26;i++){      
        if(trie[0][i]){
            fail[trie[0][i]] = 0;
            q.push(trie[0][i]);
        }
} 
    while(!q.empty()){
        int now = q.front();
        q.pop();
        for(int i=0;i<26;i++){      
            if(trie[now][i]){
                fail[trie[now][i]] = trie[fail[now]][i];
                q.push(trie[now][i]);
            }
            else//让当前节点的这个子节点
                //指向当前节点fail指针的这个子节点
                trie[now][i] = trie[fail[now]][i];
        }
    }
}

为什么在trie[now][i]不存在的情况下,也就是now号结点的编号为i的孩子不存在,就让trie[now][i]指向他的fail结点的i号结点,而不是直接指向root?他实际不是不存在的吗,为什么还要指向?

int query(string s){
    int now = 0,ans = 0;
    for(int i=0;i<s.size();i++){    
        now = trie[now][s[i]-'a'];  //从s[i]点开始寻找
        for(int j=now;j && cntword[j]!=-1;j=fail[j]){
            //一直向下寻找,直到匹配失败(失败指针指向根或者当前节点已找过).
            ans += cntword[j];
            cntword[j] = -1;    //标记,防止重复计算 
        }
    }
    return ans;
}

关于query函数:这里for里面说的是一直向下寻找,但是找到的却是他的fail结点,也就是一直在向root方向寻找,那不应该是向上寻找吗?寻找的过程难道不应该是找不到下一个字母再跳到fail指针上吗,怎么他一直跳到fail指针上,不管找没找到?

2021/4/1 13:35
加载中...