Python实现字符串匹配的KMP算法

Python实现字符串匹配的KMP算法

什么是KMP算法

KMP算法是一种字符串匹配算法,其核心思想是利用已知信息尽量减少匹配的时间。
通常来说,我们在匹配字符串时,常用的方法是从头开始,逐个字符进行比较,直到匹配成功或者匹配失败为止。但是这种方法的效率并不高,尤其是在长串匹配的情况下,就会出现时间复杂度很高的问题。
KMP算法通过建立一个next数组,存储在匹配过程中已经匹配过的信息,从而避免了重复匹配的情况,使算法的效率得以提升。

KMP算法步骤

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

  1. 计算next数组:next数组中存储着在匹配字符串过程中已经匹配过的信息,用于在匹配失败时尽量减少匹配次数。
    具体计算方法是:在模式串中,以每个字符为尾的字符串中,最长的既是该字符串的前缀又是该字符串的后缀的字符串的长度。
    例如,模式串为“ababaca”,对应的next数组为[-1,0,0,1,2,0,1]。
    其中,next[0]=-1,next[1]=0,next[2]=0,以此类推。

  2. 进行匹配:从主串的第一个字符开始,依次和模式串中的字符进行匹配。
    当匹配失败时,根据next数组的值,选择滑动到模式串中的哪一个位置继续匹配。
    当匹配成功时,返回主串中该子串的位置。

KMP算法实现示例

下面分别展示KMP算法的计算next数组和匹配主串的实现。

计算next数组

def get_next(p: str) -> list[int]:
    """
    计算next数组
    """
    m = len(p)
    next = [-1] * m
    k, j = -1, 0
    while j < m - 1:
        if k == -1 or p[k] == p[j]:
            k, j = k + 1, j + 1
            next[j] = k
        else:
            k = next[k]
    return next

以上代码中,函数get_next接受一个字符串p作为参数,返回p的next数组。
next数组初始化为-1,-1表示从模式串的开头开始匹配。
变量k和j分别指向模式串中的字符和next数组中的值,初始值为-1和0。
当p[k] == p[j]时,next[j+1]的值为k+1,表示下一次匹配时,主串的下一个字符和模式串的第k+1个字符进行比较。
否则,next[k]的值表示模式串向右移动的幅度。

匹配主串

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

以上代码中,函数kmp_search接受两个参数,s表示主串,p表示模式串,返回模式串在主串中的位置。
首先获取模式串的next数组,然后用变量i和j分别指向主串和模式串中的字符,初始值为0。
当匹配成功时,i和j分别递增,并继续匹配下一个字符。
当匹配失败时,更新j的值为next[j]。若next[j]=-1,则说明需要将模式串向右移动一位,即j+1。
当j = m时,说明匹配成功,返回主串中该子串的位置。

示例

代码如下:

s = "BBC ABCDAB ABCDABCDABDE"
p= "ABCDABD"
print(kmp_search(s,p)) # 输出15

以上代码中,主串s为BBC ABCDAB ABCDABCDABDE,模式串p为ABCDABD。
运行程序后,将返回模式串在主串中的位置,即15。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现字符串匹配的KMP算法 - Python技术站

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

相关文章

  • python调用新浪微博API项目实践

    下面我将为你详细讲解“Python调用新浪微博API项目实践”的完整攻略。 前置要求 已注册新浪微博开发者账号,获取开发者权限 已创建新浪微博开发者应用,并获取到app_key和app_secret 已安装Python开发环境,并安装requests和json模块 步骤1:获取access_token 为了能够调用新浪微博API,首先需要获取access_t…

    python 2023年6月3日
    00
  • Python float函数实例用法

    Python float函数实例用法 Python中的float()函数用于将其他数据类型转换为浮点数类型。在实际的数据处理中,浮点数类型通常用于表示非整数的数量或者量度指标。 基本语法 float([x]) 其中,x表示要转换成浮点数的值。如果不提供任何参数,则返回0.0。 示例说明 示例1:基本用法 x = 6 y = 4 result = float(…

    python 2023年5月18日
    00
  • Python简单生成随机姓名的方法示例

    下面就来详细讲解一下如何用Python生成随机姓名的方法。 生成姓氏 首先我们需要生成姓氏,通常我们可以使用已有的姓氏列表,很多基础库都可以提供这种列表。这里我们使用Python内置的random库来实现: import random # 姓氏列表 family_name_list = [‘赵’, ‘钱’, ‘孙’, ‘李’, ‘周’, ‘吴’, ‘郑’, …

    python 2023年5月20日
    00
  • python可视化实现代码

    下面我来详细讲解Python可视化实现代码的完整攻略,包括基础知识、主流可视化库、实现过程和示例说明。 基础知识 在开始Python可视化实现代码之前,需要掌握以下基础知识: Python编程语言。 数据分析基础知识,如pandas、numpy等库的使用。 数据可视化基础知识,如常见图表类型和呈现方式。 主流可视化库 在Python中实现数据可视化,有多个主…

    python 2023年5月19日
    00
  • python操作redis方法总结

    Python 操作 Redis 方法总结 Redis 简介 Redis 是一个开源的、高性能的 key-value 数据库,支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等。Redis 的特点是数据存放在内存中,读写速度非常快,同时支持持久化。 Redis 的 Python 客户端非常丰富,包括 Redis-py、Redis-py-cluster、…

    python 2023年5月14日
    00
  • matplotlib图例、标签、坐标轴刻度的字体设置方式

    下面是matplotlib图例、标签、坐标轴刻度的字体设置方式的完整攻略: 设置图例字体 在matplotlib中,可以通过legend()函数设置图例。要设置图例的字体,可以通过prop参数传递一个font对象,该对象控制图例中的字体属性。 import matplotlib.pyplot as plt import matplotlib.font_man…

    python 2023年6月6日
    00
  • Python判断回文数的三种方法实例

    Python判断回文数的三种方法实例 什么是回文数? 回文数是指正反两个方向都能够读通的数字,例如121,12321等。 方法一:将数字转为字符串,判断反转后是否相等 def is_palindrome_1(num): # 将数字转为字符串 num_str = str(num) # 反转字符串 reversed_str = num_str[::-1] # 判…

    python 2023年6月5日
    00
  • Python高效处理大文件的方法详解

    Python高效处理大文件的方法详解 处理大文件是Python程序中常见的任务之一。在处理大文件时,需要注意内存使用情况,以避免程序运行过程中出现内存溢出等问题。下面介绍一些Python高效处理大文件的方法。 读取大文件 读取大文件时,可以使用Python自带的文件读取方法。但是,如果一次读入整个文件,会占用大量的内存,因此需要一行一行地读取文件内容。下面是…

    python 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部