当前位置: 首页 > news >正文

KMP学习笔记 - Sail-With

2026-05-03

1 前缀函数

1.1 定义

对于长度为 n 的字符串 s,前缀函数 \(π_i\) 定义为:

子串 s 中最长的 相等的真前缀与真后缀 的长度。

示例

s = a b c a b c d
π = 0 0 0 1 2 3 0

1.2 暴力求法

直接枚举所有可能并逐一比较:

时间复杂度 \(O(n^3)\)

2 高效求法

2.1 优化一:相邻 π 值最多增加 1

\(s_{i+1} = s_{π_i+1}\) 时,\(π_{i+1} = π_{i} + 1\)
否则 \(π_{i+1} ≤ π_{i}\),需要回退寻找更短的公共前后缀

2.2 优化二:失配时利用 π 跳转

\(s_{i} != s_{j+1}\) 时,不是简单地将 j 减 1,而是直接跳到 \(j = π_{j}\)

点击查看 $O(n)$ 解法
vector <int> prefix(string s){int n=s.length();vector <int> pi(n+5);for(int i=2;i<=n;i++){int j=pi_{i-1};while(j>0&&s_{i}!=s_{j+1})j=pi_{j};if(s_{i}=s_{j+1})j++;pi_{i}=j;}return pi;
}

复杂度

while 循环的总回退次数不会超过总增加次数,故整体为 \(O(n)\)

3 KMP

3.1 拼接法

  • 构造新串:

S = " " + pattern + "#" + text,其中 # 是分隔符

  • 计算 S 的前缀函数:

当在 text 部分出现 \(π_{i} = n\),找到一个匹配。

  • 匹配在 text 中的起始位置:

\(i - 2n\)

4.2 直接匹配法

不实际拼接,用双指针在 text 上移动:

vector<int> kmp(string t, string s) {int j = 0;                           // j 表示模式串当前已经匹配的长度for (int i = 1; i <= m; i++) {       // i 遍历文本串while (j > 0 && t[i] != s[j + 1]) j = pi[j];if (t[i] == s[j + 1]) j++;if (j == n) {                // 成功匹配!j = pi[j];}}return result;
}

两种方法本质相同,都依赖 π 数组避免暴力回溯

4. 周期与 Border

  • 周期 p:对所有 \(i\) 满足 \(s_{i} = s_{i+p}\),则称 p 为周期。
  • Border:长度为 \(r\) 的前缀等于长度为 \(r\) 的后缀。
  • 关系

字符串有长度为 \(r\)\(border \Leftrightarrow |s| - r\) 是周期。

由 π 的定义知,最长 border 长度 = \(π_{n}\),因此 最小周期 = \(n - π_{n}\)

所有 border 可沿 π 回溯得到: \(π_{n}, π_{π_{n}}, π_{π_{π_{n}}} ...\)

4.1 字符串压缩

给定 \(s\),求最短的字符串 \(t\) 使得 \(s\)\(t\) 的多次重复拼接
\(k = n - π_{n}\)

  • \(n % k = 0\),则 \(t\) 的长度为 \(k\)
  • 否则不存在更短的压缩,答案为 \(n\)

时间复杂度 \(O(n^2)\)

http://www.jsqmd.com/news/746656/

相关文章:

  • Lotus-2三维几何密集预测框架:确定性流方法解析与应用
  • ROS2 C++开发系列12-用多态与虚函数构建可扩展的ROS2机器人行为模块
  • Vivado 2020.1 实战:手把手教你用 10G/25G Ethernet Subsystem IP 核完成 PMA 内回环仿真
  • 告别网盘限速烦恼:八大平台直链下载助手使用全指南
  • 2026年4月国内优秀的分体法兰源头厂家推荐分析,分体法兰/方法兰/扩口法兰/法兰夹/内螺纹法兰,分体法兰批发推荐分析 - 品牌推荐师
  • 3步掌握Bili2text:B站视频转文字终极指南,让学习效率翻倍!
  • APK Installer:在Windows上安装Android应用的终极解决方案
  • 2025届学术党必备的十大AI辅助论文平台横评
  • Python 爬虫进阶:Redis 缓存、持久化与高效去重实战
  • Barrier连接失败?手把手排查Kali与Windows共享键鼠的四大坑(防火墙、SSL、屏幕布局)
  • k8s ThreadSafeStore原理
  • 不懂这个,一人企业必死
  • 告别龟速!手把手教你将Jetson Xavier NX系统迁移到NVMe固态硬盘(附rootOnNVMe脚本详解)
  • 在Windows上轻松安装安卓应用:APK Installer完全指南
  • 5 分钟完成 OpenClaw 2.6.6 部署实操教程
  • Java对接OpenI国产推理框架全链路实践(含JNI/ONNX Runtime/GPU加速实测数据)
  • PCIe 5.0测试入门:手把手教你用示波器和VNA完成发射机(Tx)与接收机(Rx)一致性测试
  • Python 爬虫反爬突破:浏览器行为轨迹模拟与人机特征伪装
  • Supabase本地部署踩坑实录:从.env配置到Python Client连接,我遇到的5个坑和解决办法
  • 为什么你的网盘下载总是卡在“蜗牛模式“?LinkSwift用JavaScript重新定义文件下载体验
  • 3步解决经典游戏联机难题:IPXWrapper让老游戏重获新生
  • CAT架构:跨模态Transformer在语音技术中的实践
  • AI图像分层编辑技术:MagicQuill V2核心解析与应用
  • 别再死记硬背DP公式了!用Python手撕凸多边形三角剖分,从几何直观理解动态规划
  • 使用 Python 快速接入 Taotoken 并调用多模型 API 的完整步骤
  • R语言geodetector包实战:用栅格数据做地理探测器,从数据清洗到结果解读全流程
  • 【Python医疗配置实战指南】:20年资深架构师亲授7大高危配置陷阱与合规落地清单
  • Word GPT Plus:在Word中集成AI副驾驶的部署与深度使用指南
  • 智能水电表低功耗设计:从原理到工程实践
  • 借助多模型聚合能力为不同业务场景选择最优模型