Skip to content

Latest commit

 

History

History
10 lines (7 loc) · 1.27 KB

kmp.md

File metadata and controls

10 lines (7 loc) · 1.27 KB

KMP

代码

KMP 算法解决的是字符串匹配问题,具体来说就是对于字符串 s,我们希望找到它的一个子串 p

  • 暴力匹配:对于 s 中的每一个长度为 len(p) 的子串,我们都与 p 暴力比较
  • KMP:假设在某点 i+1 发生了失配,那么说明这个点之前都是匹配的,假设匹配的长度为 j,即 p[:j] == s[i+1-j:i+1]p[j] != s[i+1]。那么可以让 j 回退到上一个能匹配的位置 p[:k] == s[i+1-k:i+1],查看此时能否匹配(p[k] == s[i+1]?),不行的话就继续回退。
  • 可以发现 p[j-k:j] == s[i+1-k:i+1],意思是找 k 这个过程与 s 无关,因为 p 已经匹配了一部分。那么我们就是要找 p[j-k:j] == p[:k],即 p[:j] 的真前缀和真后缀的最大匹配长度,也就是 next[j]
  • 那么怎么维护 next 数组呢?假设我们已经计算出了 next[:i],要计算 next[i]。设 c = next[i-1],有 p[i-c:i] == p[:c],那么如果 p[i] == p[c],就有 p[i-c:i+1] == p[:c+1],此时 next[i] = c + 1。否则回退 c,令 c = next[c-1],也就是上一个能匹配的位置,继续比较 p[i] == p[c]。若相等,则 next[i] = c + 1,否则一直回退到不能回退了,则 next[i] = 0