String Algorithm

KMP · next 数组

逐步交互式可视化——彻底搞懂失配函数的每一个细节

// 00. 核心概念

为什么需要 next 数组?

暴力匹配在失配时会把主串指针回退,导致 O(nm) 复杂度。KMP 的天才在于:主串指针永不回退,失配时只移动模式串指针——而 next 数组告诉我们移到哪里。

// 真前缀 / 真后缀

对字符串 s真前缀是去掉至少一个尾字符的前缀,真后缀是去掉至少一个首字符的后缀。

例:abcab 的真前缀有 a, ab, abc, abca,真后缀有 b, ab, cab, bcab

// next[i] 的定义

next[i] = 模式串 t[0..i](含 i)的所有真前缀与真后缀中,相等的最长那个的长度

它的物理含义:失配于位置 i+1 时,模式串可以直接从第 next[i] 位继续比较。

// 失配时为何跳 next[j-1]?

s[i] ≠ t[j],说明 t[0..j-1] 已匹配。next[j-1] 给出了这段已匹配子串的最长公共前后缀长度,跳过去意味着:最大化地利用已知信息,跳到最近的可能匹配点

// 构建的关键:递推

用双指针 i(当前位)、k(待匹配前缀长)。t[i]==t[k] 则两者各进一步;否则 k=next[k-1] 回退——本质是在模式串自身上做 KMP。

// 01. next 数组构建 · 逐步可视化
i(当前位)
k(前缀指针)
匹配成功
匹配失败 / 回退
公共前缀
公共后缀
next[]
READY
点击 「下一步」 开始逐步构建 next 数组。每一步都会详细解释正在发生的事情。
// 02. 逐位前后缀对照表

下表展示模式串每个前缀的真前缀/真后缀集合及最长公共长度(即 next 值),帮助你建立直觉。

// 03. KMP 完整匹配 · 逐步可视化
当前匹配中
失配
完整匹配找到
当前比较位
主串 s
模式串 t(对齐当前位置)
READY
设置好主串和模式串,点击 「开始匹配」 后再点击 「下一步」