KMP模板

简介: KMP模板

KMP的套路


前言

KMP 算法是一个非常著名且高效的字符串匹配算法,

例如典型的使用场景:已知被匹配串“abaabaabca",匹配串为“abaabca”.然后判断被匹配串中是否存在匹配串,如果有返回被匹配串中匹配串的起始坐标,否则返回-1

`

一、暴力解法

常规BF思想就是套两层循环以此检索。每次匹配不成功匹配串都会返回起始点,但是若使用了kmp则不一样。

二、KMP思想(模板)

1、了解最长公共前后缀:

就例如这段字符串abaabca
||前缀 |后缀|最长公共前后缀|
|--|--|--|--
| a|无 |无|无|
|ab|a|b|0||
|aba|a、ab|a、ba|a|
|abaa|a、ab、aba|a、aa、baa|a
|abaab|a、ab、aba、abaa|b,ab,aab,baab|ab
|......|...|...|...

而最长公共前后缀有什么用呢?比如刚刚的例子如果纯bf那么当不匹配时
匹配串只能回到起始点继续匹配,但是用这个思想

abaabaabca
abaabca
在匹配到第五个字符时匹配失败,按常理就只能返回起始点了对吧,但是
abaab的最长公共前后缀是2,所以当匹配失败时可以利用这个让匹配串的下标只需返回到2的位置也就是a

那么为什么最长公共前后缀就能计算出,转移目标呢?

假设某个字符串 s 的最长共前后缀为 X="abcd...",
那么这个字符串一定是一下结构,开头是 X 结尾是 X 中间可能会有重叠,匹配到 s 的最后一个字符失败后,那我们知道 X 肯定是匹配成功了,因为 X 不包含最后一个字符。既然我们知道 X 匹配成功,那么我们一定知道,在主串中一定是从 i 位置开始且一定有一个 X 与模式串中的 X 匹配成功。

2、求得Next数组的模板(每个下标以前字符串的最长公共前缀)

def getNext(s):
    next = [0] * len(s)
    next[0] = -1
    l = len(s)
    j = 0   # 后缀位置
    k = -1  # 前缀位置
    while j < l - 1:
        if k == -1 or s[j] == s[k]:   # 若前后缀相同或者前缀位置返回最开始
            k += 1
            j += 1
            next[j] = k   # 记录
        else:
            k = next[k]   # 动规思想,返回上一个k位置的状态
    return next

其中最难理解的就是k=next[k],这行代码实质上是动态规划的一个思想

KMP整体模板

s = input()
p = input()


def getNext(p):
    next=[0]*len(p)
    pLen = len(p)

    next[0] = -1

    k = -1

    j = 0

    while j < pLen - 1:

        # p[k]表示前缀,p[j]表示后缀
        if k == -1 or p[j] == p[k]:
            j += 1
            k += 1
            next[j] = k
        else:
            k = next[k]
    return next

next = getNext(p)    
print(next)
ss = 0  # 被匹配串位置
ps = 0   #匹配串位置
sl = len(s)   
pl = len(p)
while ss < sl and ps < pl:
    if ps == -1 or s[ss] == p[ps]:  若能匹配或者ps从头开始匹配
        ps += 1
        ss += 1
    else:
        ps = next[ps]   #无法匹配则让ps返回他当前公共前后缀长度的位置

    if ps == pl:   #说明匹配成功

        print(ss-ps)
    else:
        print(-1)
相关文章
|
数据可视化 Linux
Linux centos7.x系统 下没有ens33 网卡的解决方案
此时还没有enp0s31f6网卡相关的配置信息 , 所以我们需要配置enp0s31f6网卡相关的信息
1810 0
|
2月前
|
存储 分布式计算 大数据
基于Python大数据的的电商用户行为分析系统
本系统基于Django、Scrapy与Hadoop技术,构建电商用户行为分析平台。通过爬取与处理海量用户数据,实现行为追踪、偏好分析与个性化推荐,助力企业提升营销精准度与用户体验,推动电商智能化发展。
|
11月前
|
存储 传感器 算法
使用贪心算法解决最小生成树问题
大家好,我是V哥。今天聊聊贪心算法解决最小生成树问题。面试中遇到此类题目,需掌握Prim和Kruskal算法。Prim适合稠密图,Kruskal适合稀疏图。两者时间复杂度分别为O(m log n)和O(m log m),各有优缺点。应用场景广泛,包括图像处理、传感器网络、社交网络分析等。关注V哥,全栈之路一起走。
334 6
|
11月前
|
监控 Linux
Linux systemd 服务启动失败Main process exited, code=exited, status=203/EXEC
通过以上步骤,可以有效解决 systemd 服务启动失败并报错 `Main process exited, code=exited, status=203/EXEC` 的问题。关键在于仔细检查单元文件配置、验证可执行文件的有效性,并通过日志分析具体错误原因。确保可执行文件路径正确、文件具有执行权限,并且可以独立运行,将有助于快速定位和解决问题。
5034 7
|
Java Android开发
IDEA设置项目编码格式【修改为GBK 或 UTF-8】
这篇文章介绍了在IntelliJ IDEA中如何设置项目编码格式,包括将项目编码修改为GBK或UTF-8的详细步骤和图解。
21251 12
IDEA设置项目编码格式【修改为GBK 或 UTF-8】
|
算法
串ababaaababaa的next和串ababaabab的nextval
本文介绍了计算字符串的next数组和nextval数组的方法,通过分析两个具体的例子来展示如何计算这些数组,这些数组通常用于KMP算法中。
946 0
串ababaaababaa的next和串ababaabab的nextval
|
机器学习/深度学习 数据可视化 数据挖掘
数据降维 | MATLAB实现T-SNE降维特征可视化
数据降维 | MATLAB实现T-SNE降维特征可视化
|
数据可视化 算法 Java
国人开发的JAVA三维可视化组件:Matplot 3D for JAVA(V3.0) 一个业余程序员用纯JAVA开发的科学数据可视化组件包
Matplot3D for JAVA(V3.0) 是一个基于JAVA SE 1.8环境开发的三维图形图表组件。 组件由纯JAVA SE 实现(Pure Java) ,封装为一个jar包,jar文件大小不超过300KB。内含自主研发的三维几何造型、绘制算法,无需依赖OpenGL、DriectX、JAVA 3D或JAVAFX等等第三方库,其只依托JRE自带的类库即可(即只需安装了JAVA就可使用),可以非常方便的将Matplot3D for JAVA(V3.0)显示面板嵌入到自己JAVA GUI程序中,或者生成图片用于Web动态页面中。
1293 0
国人开发的JAVA三维可视化组件:Matplot 3D for JAVA(V3.0)  一个业余程序员用纯JAVA开发的科学数据可视化组件包
|
存储 NoSQL 关系型数据库
何时使用MongoDB而不是MySql
MySQL 和 MongoDB 是两个可用于存储和管理数据的数据库管理系统。MySQL 是一个关系数据库系统,以结构化表格格式存储数据。相比之下,MongoDB 以更灵活的格式将数据存储为 JSON 文档。两者都提供性能和可扩展性,但它们为不同的应用场景提供了更好的性能。
599 1
何时使用MongoDB而不是MySql