浅谈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数据结构和算法之数组 在本教程中,我们将学习Java中的数组数据结构和对应的算法。让我们先来了解什么是数组。 什么是数组? 数组是一个同类型数据元素的集合,在内存中连续存储。数组具有索引性,我们可以使用索引值来访问数组中的元素。 声明和初始化数组 在Java中,声明一个数组需要指定以下三个参数: 数组的类型 数组的名称 数组的大小 以下是一个…

    数据结构 2023年5月17日
    00
  • C语言深入讲解链表的使用

    C语言深入讲解链表的使用 什么是链表? 链表是一种常用的数据结构,它的存储方式是通过指针相互连接实现的。链表是由若干个节点(node)构成的,每个节点都存储着一些信息和指向下一个节点的指针。 链表实现的基本操作 链表的基本操作包括插入节点、删除节点以及遍历链表。我们下面将通过代码示例详细介绍这些操作。 插入节点 链表的插入节点操作是指在链表的某一位置插入一个…

    数据结构 2023年5月17日
    00
  • MySQL索引背后的数据结构及算法原理详解

    《MySQL索引背后的数据结构及算法原理详解》是一篇介绍MySQL索引背后的数据结构和算法原理的文章。MySQL索引是提高查询效率的一个重要工具,理解其背后的数据结构和算法原理对于提高数据库性能和优化查询操作是非常有帮助的。 本文主要分为以下三部分: MySQL索引背后的数据结构 索引的几种常见数据结构及其优缺点 索引的算法原理 MySQL索引背后的数据结构…

    数据结构 2023年5月17日
    00
  • C语言 结构体数组详解及示例代码

    C语言 结构体数组详解及示例代码 结构体是C语言中最为基础的数据结构之一,它可以将多个数据类型组合成一个整体,方便地进行访问和管理。而结构体数组则是将多个相同结构体类型的变量按照一定规律排列在一起的一种数据结构。本文将详细讲解C语言中结构体数组的使用方法及示例代码。 定义结构体 首先,我们需要定义一个结构体类型。结构体类型需要指定名称、成员变量及其数据类型:…

    数据结构 2023年5月17日
    00
  • 排序算法之详解选择排序

    引入 选择排序顾名思义是需要进行选择的,那么就要问题了,选择到底是选择什么呢? 选择排序的选择是选择数组中未排序的数组中最小的值,将被选择的元素放在未排序数组的首位 如果你对 ‘未排序数组’ , ‘选择’ 的概念不理解,那么你可以看看下面的图 思路 有了上面的一些基础之后,我们再来说说选择排序算法的思路 不断的选择未排序数组中最小的值,将其与未排序数组的首位…

    算法与数据结构 2023年4月25日
    00
  • Java数据结构之栈与队列实例详解

    Java数据结构之栈与队列实例详解攻略 简介 栈和队列是常见的数据结构,在Java中也有对应的实现方式。本文将介绍栈和队列的概念、常见实现方式、应用场景和两个示例。 栈 概念 栈是一种具有后进先出(Last In First Out)特性的数据结构。栈可以使用数组或链表实现。 常见实现方式 基于数组的栈实现 使用数组作为底层存储结构实现栈时,需要注意栈顶指针…

    数据结构 2023年5月17日
    00
  • Go语言数据结构之二叉树必会知识点总结

    Go语言数据结构之二叉树必会知识点总结 二叉树是一种非常重要的数据结构,它被广泛应用于算法、数据处理等领域。在Go语言中,使用二叉树可以实现很多高级数据结构和算法。本文将为大家介绍二叉树相关的基本知识和操作,以及如何利用Go语言实现二叉树。 什么是二叉树? 二叉树是一种树形结构,由一个根节点和两个子树组成。它的每个节点最多有两个子节点,称为左子节点和右子节点…

    数据结构 2023年5月17日
    00
  • 一些常见的字符串匹配算法

    作者:京东零售 李文涛 一、简介 1.1 Background 字符串匹配在文本处理的广泛领域中是一个非常重要的主题。字符串匹配包括在文本中找到一个,或者更一般地说,所有字符串(通常来讲称其为模式)的出现。该模式表示为p=p[0..m-1];它的长度等于m。文本表示为t=t[0..n-1],它的长度等于n。两个字符串都建立在一个有限的字符集上。 一个比较常见…

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