逐步交互式可视化——彻底搞懂失配函数的每一个细节
暴力匹配在失配时会把主串指针回退,导致 O(nm) 复杂度。KMP 的天才在于:主串指针永不回退,失配时只移动模式串指针——而 next 数组告诉我们移到哪里。
对字符串 s,真前缀是去掉至少一个尾字符的前缀,真后缀是去掉至少一个首字符的后缀。
例:abcab 的真前缀有 a, ab, abc, abca,真后缀有 b, ab, cab, bcab。
next[i] = 模式串 t[0..i](含 i)的所有真前缀与真后缀中,相等的最长那个的长度。
它的物理含义:失配于位置 i+1 时,模式串可以直接从第 next[i] 位继续比较。
当 s[i] ≠ t[j],说明 t[0..j-1] 已匹配。next[j-1] 给出了这段已匹配子串的最长公共前后缀长度,跳过去意味着:最大化地利用已知信息,跳到最近的可能匹配点。
用双指针 i(当前位)、k(待匹配前缀长)。t[i]==t[k] 则两者各进一步;否则 k=next[k-1] 回退——本质是在模式串自身上做 KMP。
下表展示模式串每个前缀的真前缀/真后缀集合及最长公共长度(即 next 值),帮助你建立直觉。