KMP,字符串算法万恶的源头
默认下文所有字符串的下标从
学会 KMP,要先学会求 border。
border 是一个字符串
其求法为:假设当前已经求出了
- 如果
s_{tp+1}=s_i ,则\text{border}_i 就是tp ,赋值并结束操作。 - 反之,让
tp\leftarrow \text{border}_{tp} 。 - 如果此时
tp=0 ,则\text{border}_i=0 ,结束操作,否则回到第一步继续操作。
其实就是一个让 感性理解就是线性的。
至此,border 已经求完了。
:::info[代码]
fo(i,1,n){
int tp=border[i-1];
while (tp&&s[i]!=s[tp+1])
tp=border[tp];
if (s[i]==s[tp+1])
tp++;
border[i]=tp*(i>1);
}
:::
在字符串
KMP 算法可以用来优化 dp。比如
P3082 这个题,在求出 border 之后,dp 的过程相当于 KMP 匹配字符串的算法,可以优化时间复杂度。