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的模 ...
随机推荐
- golang的编程规范
我不配写这个,但是我配转发一下. https://github.com/uber-go/guide 这个规范,每次看都有收获. 主要是7月份好像没啥内容可写了,水一篇
- Java REST API 三层架构项目目录规划与使用建议
一. 背景介绍 当前,我们使用 Spring Boot + Mybatis + Maven 技术栈,按照微服务设计的要求(小而自治)开发 Java 应用,不推荐和使用 Module 实现项目分层. 二 ...
- PWN手的成长之路-01-rip
首先启动题目环境,并下载题目的附件. 远程nc连接一下,发现程序就是把用户输入再次输出,并加了几句话. 之后从附件下手,用file查看文件的详细信息.发现是一个linux的可执行程序. 使用check ...
- 飞腾板卡设计方案:818-SOM-NF241 飞腾2000/4 TYPE 10模块
FT2000/4全国产化COMe模块是按照PICMG COM Express规范设计,兼容COM express TypelO的pin脚定义,尺寸为mini module(84mm x75mm).CP ...
- 276-16路AD、10路DA嵌入式振动测控模块
一.板卡概述: 本板卡采用TI OMAP-L138(浮点DSP C6748+ARM9) +Xilinx Spartn-6 FPGA为主控芯片,实现数据处理与现场控制为一体的智能振动测试模块,AD部分由 ...
- MFC一些必要的名词(二)
UI:Windows 程序分为「程序代码」和「UI(User Interface)资源」两大部份,两部份最后以RC 编译器整合为一个完整的EXE 文件( 图 1-1 ).所谓UI 资源是指功能菜单.对 ...
- P10912 [蓝桥杯 2024 国 B] 数星星
P10912 [蓝桥杯 2024 国 B] 数星星 题意简介 给定一棵 \(n\) 个节点的树和 \(L,R\),询问有多少个子图 \(G\),满足该子图是一棵树,树中存在一个节点 \(u\),其度数 ...
- kubernetes NFS Provisioner 配置
注意使用这个组件必须要提前配置好nfs服务器 配置nfs-server 我选择在master节点上创建nfs服务端 yum install -y rpcbind nfs-utils 配置nfs vi ...
- KAL1 LINUX 官方文档之容器---安装Docker
要在Kali上安装Docker,你需要记住已经有一个名为 "docker "的包,因此必须用不同的名字安装Docker.如果你安装了这个docker,你将永不能使用容器那个版本.我 ...
- 常见问题解决 --- We're sorry but doesn't work properly without JavaScript enabled. Please enable it to continue.
这是vue首页的默认页面,这个报错的原因可能是因为前端路由失败,我的是因为vue的后台nginx代理没有正确配置,配置一下后台代理接口即可