加载中...

KMP自动机

KMP 自动机,实际上就是存储单个模式串的 AC 自动机。

在求出模式串的 \(next\) 数组后,便可以利用 \(next\) 数组来构造 KMP 自动机。

状态定义

\(to_{i,j}\):考虑模式串的前 \(i\) 个字符构成的前缀。往末尾添加一个字符 \(j\),形成新串末尾位置的 \(next\) 值(即与新串某个前缀相同的最长后缀,注意这里可以是真后缀)。

状态转移

类似于 AC 自动机 \(fail\) 指针的路径压缩。

string s;
cin >> s;
int n = s.size();
s = " " + s;

// get next[]
ne[1] = 0;
for(int i = 2, j = 0; i <= n; i ++){
    while(j && s[i] != s[j + 1]) j = ne[j];
    if(s[i] == s[j + 1]) j ++;
    ne[i] = j;
}

// build KMP automaton
to[0][s[1] - 'a'] = 1;
for(int i = 1; i <= n; i ++){
    for(int j = 0; j < 26; j ++){ // 枚举所有可能出现在后面的字符
        if(i < n && s[i + 1] - 'a' == j) to[i][j] = i + 1; // 整个串也可以作为前缀
        else to[i][j] = to[ne[i]][j];
    }
}

时间复杂度

\(O(|\sum| * n)\)

posted @ 2026-06-30 16:09  小橘奏  阅读(11)  评论(0)    收藏  举报