KMP(Knuth-Morris-Pratt )算法-模式串lps(Longest Prefix Suffix)最长相同前后缀长度数组算法证明
被KMP算法折磨了几天,终于搞明白lps数组,或者叫next数组计算过程中非常关键点的原理,这里着重在证明为什么这样计算。
1 public static int[] buildLPS(String pat) {
2 int n = pat.length();
3 int[] lps = new int[n];
4
5 int prefixLen = 0; // 当前已匹配的最长前后缀长度
6 int i = 1; // 正在处理 lps[i]
7
8 while (i < n) {
9 if (pat.charAt(i) == pat.charAt(prefixLen)) {
10 prefixLen++;
11 lps[i] = prefixLen;
12 i++;
13 } else if (prefixLen > 0) {
14 // 需要证明的部分
15 prefixLen = lps[prefixLen - 1];
16 } else {
17 lps[i] = 0;
18 i++;
19 }
20 }
21 return lps;
22 }
以上是计算lps数组的方法,lps数组表示了位于当前坐标i时,pat[0...i]中最长相同前后缀的长度。
line 9-13 说明了当pat[i] = pat[prelen]的时候,只需要继续沿用之前的最长前后缀长度就可以了
难点在理解line 15 为什么回退的时候 prefixLen=lps[prefixLen-1]而不是其他的值。以下是是证明过程:
当前len = lps[i-1],及pat[0..i-1]的最长相同前后缀长度,及pat[0...len-1] = pat[i-len..i-1]。
当pat[len] != pat[i]时,表示不能继续沿用之前的len = lps[i-1],
而是需要重新寻找一个t,满足pat[0...t-1]+pat[t] = pat[i-t...i-1]+pat[i],相当于pat[0...t-1] = pat[i-t...i-1],根据lps定义,及我们需要找一个pat[0...i-1]的长度为t且相同的前后缀。
已知len=lps[i-1]是不满足条件的,所以t<len。
目前
1. pat[0...len-1] = pat[i-len..i-1]
2. pat[0...t-1] = pat[i-t...i-1]
3. t<len
可知
pat[0...t-1]+pat[t..len-1] =pat[i-len..i-t-1]+pat[i-t...i-1]
由此可得 pat[i-t...i-1] (长度t) 是pat[0...len-1] = pat[0...t-1]+pat[t..len-1] 的后缀
又因为pat[0...t-1](长度t) 是pat[0...len-1] 的前缀
所以t是pat[0...len-1]的某一个相同的前后缀的长度。
t的最大值是lps[len-1], 及pat[0..len-1]的最长相同前后缀长度。
一个比较好体现这个过程的例子:aabaabaaa
lps是 [0, 1, 0, 1, 2, 3, 4, 5, 2]

KMP(Knuth-Morris-Pratt )算法-模式串lps(Longest Prefix Suffix)最长相同前后缀长度数组算法证明的更多相关文章
- 我所理解的 KMP(Knuth–Morris–Pratt) 算法
假设要在 haystack 中匹配 needle . 要理解 KMP 先需要理解两个概念 proper prefix 和 proper suffix,由于找到没有合适的翻译,暂时分别称真实前缀 和 真 ...
- KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想
KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想 阅读本文之前,您最好能够了解 KMP 算法解决的是什么问题,最好能用暴力方式(Brute Force)解决一下该问题 ...
- 字符串匹配算法--KMP字符串搜索(Knuth–Morris–Pratt string-searching)C语言实现与讲解
一.前言 在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息 ...
- 【kmp+求所有公共前后缀长度】poj 2752 Seek the Name, Seek the Fame
http://poj.org/problem?id=2752 [题意] 给定一个字符串,求这个字符串的所有公共前后缀的长度,按从小到达输出 [思路] 利用kmp的next数组,最后加上这个字符串本身 ...
- POJ 2752 (kmp求所有公共前后缀长度)
<题目链接> <转载于> 题目大意: 给出一个字符串str,求出str中存在多少子串,使得这些子串既是str的前缀,又是str的后缀.从小到大依次输出这些子串的长度.即输出该 ...
- KMP + 求相等前后缀--- POJ Seek the Name, Seek the Fame
Seek the Name, Seek the Fame Problem's Link: http://poj.org/problem?id=2752 Mean: 给你一个字符串,求这个字符串中有多少 ...
- 【算法】串的模式匹配算法(KMP)
串的模式匹配算法 问题: 求子串位置的定位函数如何写? int index(SString S,SString T,int pos); 给定串S,子串T,问T在 ...
- 模式串 从 0 开始的KMP算法
/** * 看了 b站视频 BV1jb411V78H 对KMP有了一点理解,然后我写了这个代码 * 这个代码和视频里面的有一点不同,字符串是从 0 开始的,而不是从1 开始的 * 希望能够帮到学习KM ...
- 利用KMP算法解决串的模式匹配问题(c++) -- 数据结构
题目: 7-1 串的模式匹配 (30 分) 给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串 ...
- 条件随机场CRF(二) 前向后向算法评估标记序列概率
条件随机场CRF(一)从随机场到线性链条件随机场 条件随机场CRF(二) 前向后向算法评估标记序列概率 条件随机场CRF(三) 模型学习与维特比算法解码 在条件随机场CRF(一)中我们总结了CRF的模 ...
随机推荐
- RPCS3模拟器 玩COD3等独占带体感手柄的纯键盘操作方法
好不容易找到可玩的cod3,结果用的rpcs3模拟器,这款纯键盘模拟体感操作非常之山炮,不如海豚模拟器有单独的模拟体感键位设置,卡了好几次过不去,最后发现一个一劳永逸的方法: 进入游戏后,选设置-游戏 ...
- win2003 做FTP服务端时win2008 r2 竟然无法访问的问题
首先,环境中必须开启自带防火墙,03中允许了20,21端口,win7测试时关闭被动模式,以主动模式连接成功,目测端口连接情况只有21.可是08 r2 做客户端访问时竟然不行?!不论被动还是主动,一律失 ...
- PHP OOP 面向对象进阶 27 个问题让你充分了解对象特性
PHP OOP 面向对象进阶 27 个问题让你充分了解对象特性 这里整理了一些 PHP 面向对象编程中容易搞混的知识点,很多都是面试常考题.不过学这些不只是为了应付面试,更重要的是真正搞懂面向对象编程 ...
- 3. Ollama 安装,流式输出,多模态,思考模型
3. Ollama 安装,流式输出,多模态,思考模型 @ 目录 3. Ollama 安装,流式输出,多模态,思考模型 接入ollama本地模型 本地大模型安装 基于spring-ai使用 上我们在 O ...
- Megatron-LM Efficient AI training system
Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM 目录 Efficient Large-S ...
- SystemVerilog for Design Edition 2 Chapter 10 SystemVerilog Interfaces
SystemVerilog for Design Edition 2 Chapter 10 SystemVerilog extends the Verilog language with a powe ...
- nysql:read_me_recover_tn勒索恢复
联系:手机/微信(+86 17813235971) QQ(107644445) 标题:read_me_recover_tn勒索恢复 作者:惜分飞版权所有[未经本人同意,不得以任何形式转载,否则有进一步 ...
- 【vite】vite环境变量.env文件的配置及使用,环境变量读取问题
文章目录 前言 1. 环境变量使用场景 2. 创建.env文件 3. 在应用程序中使用环境变量 3.1. 输出结果(开发环境): 3.2. 输出结果(生产环境): 4. 在 vite 中使用环境变量 ...
- [fastgrind] 一个轻量级C++内存监控及可视化开源库
目录 Fastgrind 引言 简介 仓库结构 快速开始 编译 testcase 运行 testcase 调用堆栈 Report 如何在你的项目中使用 手动插桩的使用方法 自动插桩的使用方法 fast ...
- CSP-S模拟35
CSP-S模拟35 bushi 什么神人场??? A. 集合 (set) jb. 尼玛怎么又是 bitset master 场上只会 \(O(\frac{n^2}{w})\) 做法. Code: B. ...