KMP

怎么求KMP

border是KMP中的关键概念,border就是一个字符串,它既是某个串的前缀,又是后缀。

定义 \(nxt_i\) 是对于前 \(i\) 个字符串的最长border,在前缀相同部分的末尾位置。

\(nxt_i\) 的作用是,如果在 \(a_{i+1}\) 失配,作为模板串不会从头开始匹配,而是从 \(nxt_i\) 开始匹配。因为前后缀是相同的,因为前后缀是相同的,文本串中对应 \(1 \sim nxt_i\) 的位置肯定匹配成功了。

假设 \(b\) 是模板串,\(a\) 是文本串,求有多少个匹配:

int j=0;
for(int i=1;i<=lena;i++){
    while(b[j+1]!=a[i]&&j!=0)j=nxt[j];
    if(b[j+1]==a[i])j++;
    if(j==lenb){
        v.push_back(i-lenb+1);
    }
}

\(nxt_i\) 是给一个指针 \(j\) ,用模板串自己的前缀匹配后缀。

int j=0;
for(int i=2;i<=lenb;i++){
    while(b[j+1]!=b[i]&&j!=0)j=nxt[j];
    if(b[j+1]==b[i])j++;
    nxt[i]=j;
}

画图,发现文本串指针增加 \(lena\) 次,模板串匹配时最多向前 \(lenb\) 次,时间复杂度 \(O(lena+lenb)\)

KMP求最小循环节

画图。最小循环节是 \(n-nxt_n\)

posted @ 2026-08-03 10:54  TanHaoren  阅读(3)  评论(0)    收藏  举报