浅谈Python描述数据结构之KMP篇

浅谈Python描述数据结构之KMP篇

简介

本篇文章将着重介绍KMP算法,其中包含KMP算法的基本原理、实现步骤以及Python代码实现示例。KMP算法是一种高效的字符串匹配算法,它可以在O(m+n)的时间内完成字符串的匹配操作,其中m和n分别为主串和模式串的长度。

基本原理

KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,它的基本思想是通过“部分匹配表”来避免不必要的比较操作。具体来说,它在匹配过程中,当某个字符匹配失败时,不是直接跳转到下一个字符进行比较,而是根据已匹配的结果来确定下一个比较的位置。这个过程中,部分匹配表就发挥了重要作用,它能够提供已匹配的信息,以及在匹配失败时的跳转位置。

实现步骤

KMP算法的实现步骤主要包括以下几个部分:

  1. 构建部分匹配表
  2. 在主串和模式串中进行匹配
  3. 根据部分匹配表调整匹配位置

其中,构建部分匹配表是整个算法中最重要的一步,需要单独解释。

构建部分匹配表

部分匹配表是模式串本身的一个数组,用来储存模式串的每个位置上,从头开始的子串的最长公共前后缀长度。具体地,设模式串为p,p的长度为m,则部分匹配表的长度也为m。在第i个位置上,部分匹配表的值表示p[:i+1]这个子串的最长公共前后缀长度。需要注意的是,这里的公共前后缀必须是非自身重复的,否则会出现算法错误。以p="ABCDABD"为例,它的部分匹配表为:

字符串 A B C D A B D
部分匹配表 0 0 0 0 1 2 0

在主串和模式串中进行匹配

在进行匹配时,我们将主串和模式串对齐,从左到右逐个比较,步骤如下:

  1. 如果当前字符匹配成功,即S[i]==P[j],则i++,j++
  2. 如果当前字符匹配失败,则根据部分匹配表j的值来调整j的位置。具体地,设当前子串为S[i-k:i],部分匹配表为next[],则j=next[k]。
  3. 如果j=-1,则表示主串的当前位置i无法与模式串中任何位置匹配,此时i++,j++

需要注意的是,对于模式串的第一个字符,我们是不做比较,而是从第二个字符开始匹配。

根据部分匹配表调整匹配位置

在匹配失败时,我们需要根据部分匹配表来调整j的位置,具体地,设当前子串为S[i-k:i],部分匹配表为next[],则j=next[k]。需要注意的是,如果next[k]大于0,则部分匹配表的值本身就蕴含了“跳跃”的信息,即主串中不必从i-k这个位置开始逐个比较,而是可以直接跳到j=next[k]这个位置,从下一个字符开始比较。

Python代码实现示例

下面是一个简单的Python实现示例:

def kmp_search(s, p):
    """
    KMP算法,用于字符串匹配
    """
    m, n = len(s), len(p)
    next = get_next(p)
    i, j = 0, 0
    while i<m and j<n:
        if j==-1 or s[i]==p[j]:
            i += 1
            j += 1
        else:
            j = next[j]
    if j == n:
        return i - j
    return -1

def get_next(p):
    """
    构建部分匹配表
    """
    n = len(p)
    next = [-1] * n
    i, j = 0, -1
    while i<n-1:
        if j==-1 or p[i]==p[j]:
            i += 1
            j += 1
            next[i] = j
        else:
            j = next[j]
    return next

下面是一个简单的例子,演示了如何在主串s中查找模式串p。

s = "BBC ABCDAB ABCDABCDABDE"
p = "ABCDABD"
pos = kmp_search(s, p)
if pos == -1:
    print("Pattern not found in string.")
else:
    print(f"Pattern found at position {pos}.")

示例说明

上述示例中,我们依次完成了以下操作:

  1. 首先定义了一个主函数kmp_search和一个辅助函数get_next。
  2. 在kmp_search函数中,我们首先使用get_next函数来生成部分匹配表,然后设置i,j的初值为0。
  3. 在while循环的过程中,我们依次比较s[i]和p[j],如果匹配成功,则继续下一组比较;如果匹配失败,则根据部分匹配表重新设置j的位置。
  4. 最后,如果j等于n,说明p已经完整匹配成功,返回i-j作为匹配位置;否则,返回-1表示匹配失败。
  5. 在最后一个代码块中,我们定义了一个主串s和一个模式串p,然后使用kmp_search函数来查找p在s中出现的位置,并将结果打印输出。

结论

KMP算法是一种高效的字符串匹配算法,相比于朴素的字符串匹配算法,它能够避免无谓的比较操作,减少了算法的时间复杂度。在实际应用中,KMP算法具有较为广泛的使用场景,如文本匹配、模式识别、音频处理等。掌握KMP算法的原理和实现方法,对于提高程序的效率和准确性具有非常重要的意义。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈Python描述数据结构之KMP篇 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Java数据结构之复杂度篇

    《Java数据结构之复杂度篇》是一篇关于算法复杂度分析的文章。本文主要介绍了如何使用大O符号来表示算法的时间复杂度、如何计算最坏情况下的时间复杂度、如何判断嵌套循环的时间复杂度、如何分析递归算法的时间复杂度等。 大O符号 大O符号是一种表示算法时间复杂度的符号,通常用于表示最坏情况下的时间复杂度。例如,如果某个算法的时间复杂度为O(n),则表示最坏情况下这个…

    数据结构 2023年5月17日
    00
  • 「学习笔记」AC 自动机

    「学习笔记」AC 自动机 点击查看目录 目录 「学习笔记」AC 自动机 算法 问题 思路 代码 例题 Keywords Search 玄武密码 单词 病毒 最短母串 文本生成器 背单词 密码 禁忌 前置:「学习笔记」字符串基础:Hash,KMP与Trie。 好像对例题的讲解越来越抽象了? 算法 问题 求 \(n\) 个单词在一个长度为 \(m\) 的文章里出…

    算法与数据结构 2023年5月5日
    00
  • 滑动窗口总结

    前言 滑动窗口是双指针的一种特例,可以称为左右指针,在任意时刻,只有一个指针运动,而另一个保持静止。滑动窗口路一般用于解决特定的序列中符合条件的连续的子序列的问题。 好处:时间复杂度 O(n^2) —> O(n) 一、算法应用场景 关键词: 1.满足XXX条件(计算结果、出现次数、同时包含) 2.最长/最短/或最值 3.子串/子数组/子序列 最最最…

    算法与数据结构 2023年4月17日
    00
  • NDK 数据结构之队列与栈等的实现

    NDK 数据结构之队列与栈等的实现 引言 Android NDK 是 Android 开发工具包的一部分,可以用 C 和 C++ 编写应用程序和库。NDK 带来了许多好处,例如可以针对不同的平台进行优化,可以通过调用底层 C/C++ 库实现更高效的算法等。 在本篇文档中,我们将探讨如何使用 NDK 实现一些基础的数据结构,包括队列、栈等等。 队列的实现 队列…

    数据结构 2023年5月17日
    00
  • JavaScript数据结构与算法

    JavaScript数据结构与算法完整攻略 什么是数据结构与算法 数据结构和算法是计算机科学的重要组成部分,常用于解决数据处理问题的方法与技术。数据结构是指存储和组织数据的方式,而算法则是解决数据处理问题的途径和方法。 数据结构分类 数据结构可分为以下几类: 数组 —— 存储有序元素集合的线性结构; 栈 —— 一种后进先出的数据结构; 队列 —— 一种先进先…

    数据结构 2023年5月17日
    00
  • CSP-何以包邮?

    题目描述 新学期伊始,适逢顿顿书城有购书满 x 元包邮的活动,小 P 同学欣然前往准备买些参考书。一番浏览后,小 P 初步筛选出 n 本书加入购物车中,其中第 i 本(1≤i≤n)的价格为 ai 元。考虑到预算有限,在最终付款前小 P 决定再从购物车中删去几本书(也可以不删),使得剩余图书的价格总和 m 在满足包邮条件(m≥x)的前提下最小。 试帮助小 P …

    算法与数据结构 2023年5月11日
    00
  • Golang实现数据结构Stack(堆栈)的示例详解

    Golang实现数据结构Stack(堆栈)的示例详解 什么是Stack? Stack,也称为堆栈,是一种先进后出(Last In First Out, LIFO)的数据结构。举个例子,比如一堆书,你按照一定的顺序叠起来,然后你想要拿出第一本,你需要先拿掉上面的书才能取到下面的。这就是典型的堆栈模型。 在编程中,Stack也是一种非常常见的数据结构,特别是在函…

    数据结构 2023年5月17日
    00
  • 【牛客小白月赛70】A-F题解【小d和超级泡泡堂】【小d和孤独的区间】【小d的博弈】【小d和送外卖】

    比赛传送门:https://ac.nowcoder.com/acm/contest/53366 难度适中。 ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?? 阅读原文获得更好阅读体验:https://www.erikt…

    算法与数据结构 2023年4月17日
    00
合作推广
合作推广
分享本页
返回顶部