[模板] KMP算法/Border

KMP 算法

KMP (Knuth-Morris-Pratt) 算法是一种在线性时间内匹配文本串和模式串的算法.

称字符串的 Border 集合为

\[ \operatorname {Border} (S) = \{Pre_S(j) | Pre_S(j) = Suf_S(n - j + 1) \land j \not= n \} \]

称字符串 \(S\) 的最长 Border 为 \(fail(S)\), 或者 \(next(S)\). 容易发现递归枚举 \(fail(S), fail(fail(S)), \dotsc\) 可以得到 \(S\)\(\operatorname {Border}\) 集合.

把每个位置 \(p\) 连向 \(fail(p)\) (包括 \(0\) 号节点), 可以得到一棵以 \(0\) 号节点为根的树, 称为 Border tree.

KMP 算法可以在线性时间内得到字符串 \(S\) 每个前缀的 \(fail\) 函数, 并可以利用它进行字符串的匹配.

求 Border 和匹配

int n,m;
char s1[nsz],s2[nsz];

int nxt[nsz];
void getnext(char *s,int n){
    int l=0; //l means the length of prefix matched
    nxt[1]=0;
    rep(i,2,n){
        while(l&&s[l+1]!=s[i])l=nxt[l];
        if(s[l+1]==s[i])++l;
        nxt[i]=l;
    }
}

int pl[nsz],pp=0;
void match(){ //s2->s1
    pp=0;
    int l=0; // the length of prefix of m matched
    rep(i,1,m){
        while(l&&s2[l+1]!=s1[i])l=nxt[l];
        if(s2[l+1]==s1[i])++l;
        if(l==n){pl[++pp]=i-l+1;l=nxt[l];}
    }
}

转载于:https://www.cnblogs.com/ubospica/p/11118847.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值