PrepStack · Markdown HTML

KMP / 前缀函数字符串匹配

字符串匹配、哈希与回文 · HTML

数学 / 逻辑形态

pi[i] 是 pattern[0..i] 的最长真前缀且同时为后缀的长度;扫描时 j 为当前可复用前缀长度。

识别信号

容易误判的相似信号

SignalWhy it is different
大量模式多模式共享结构应考虑 Trie 或多模式自动机。
近似匹配允许编辑或误差时需 DP 或其他距离算法。

核心不变量

扫描文本位置前,j 是已处理文本后缀等于模式前缀的最大长度。

状态、转移与处理顺序

ItemDefinition
State模式 prefix-function 数组 pi、当前匹配长度 j、匹配起点列表。
Transition失配沿 pi[j-1] 回退;相等则 j++;j==m 时报告并回退以允许重叠。
Frontier / order文本指针只右移;模式前沿 j 沿 border 链回退而不重读文本。

Python 骨架

def kmp_find_all(text, pat):
    if not pat: return list(range(len(text)+1))
    pi = [0] * len(pat)
    j = 0
    for i in range(1, len(pat)):
        while j and pat[i] != pat[j]: j = pi[j-1]
        if pat[i] == pat[j]: j += 1
        pi[i] = j
    ans, j = [], 0
    for i, ch in enumerate(text):
        while j and ch != pat[j]: j = pi[j-1]
        if ch == pat[j]: j += 1
        if j == len(pat):
            ans.append(i-len(pat)+1)
            j = pi[j-1]
    return ans

正确性思路

  1. pi 记录每个模式前缀可复用的最长 border。
  2. 失配后更长候选已被否定,跳到 pi[j-1] 不漏解。
  3. j==m 当且仅当完整模式是当前文本后缀。
  4. 文本不回退且 j 的总涨落线性。

复杂度

TimeSpaceParameters
O(n+m)O(m) 加输出n 为文本长度,m 为模式长度

边界条件

错误模式

PatternWhy it fails / fix
失配只清零丢掉可复用 border。
只回退一次一次跳转后仍可能失配,必须 while。
完整匹配后不回退会越界并漏重叠匹配。

选择与排除规则

相关模板

RelationTemplateBoundary
流式组合字符串解析 / Token 状态机匹配是 token 解析的一部分
替代匹配Rolling Hash / Rabin–Karp需要子串哈希与多长度比较
contrast子序列 DP需要连续模式匹配而不是可跳过的公共序列。
多模式扩展Trie 前缀树多个模式共享前缀

原创微型例子

环节内容
Result起点 0 与 2。
Scenario文本 ababab,模式 abab。
Walkthrough第一次匹配后 j 回到 border“ab”的长度 2,后两个字符构成重叠匹配。

Recall prompts

我的补充