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中time、datetime模块的使用

    下面我来详细讲解一下Python中time和datetime模块的使用。 一、time模块 1.1 time模块概述 time模块是Python的一个标准库,用于处理时间和日期相关的函数和类。它提供了一种简单的方式来表示时间,即以自1970年1月1日00:00:00 UTC以来的秒数来表示,并提供了一些函数以支持常见的时间和日期操作,如获取当前时间、时间戳转…

    python 2023年6月2日
    00
  • 浅谈Matplotlib简介和pyplot的简单使用——文本标注和箭头

    下面是“浅谈Matplotlib简介和pyplot的简单使用——文本标注和箭头”的完整攻略: 1. Matplotlib简介 Matplotlib是一个数据可视化库,它能够帮助Python开发者更便捷地创建各种图表。它可以处理各种图表类型,例如线图、柱状图、散点图等等。Matplotlib的核心是pyplot模块,我们通过import matplotlib.…

    python 2023年5月18日
    00
  • python中的tkinter库弹窗messagebox详解

    Python中的tkinter库弹窗 messagebox详解 1. 概述 tkinter是Python中常用的GUI库,它提供了常见的组件,如按钮、标签、文本框等等。而messagebox就是其中一个常用的弹窗组件。 在Python中,要使用messagebox组件,需要先从tkinter库导入它: from tkinter import messageb…

    python 2023年5月18日
    00
  • python实现给字典添加条目的方法

    当我们需要在Python中创建一个新的字典或修改一个已有的字典时,需要给该字典添加一个或多个条目。Python提供了多种方法来实现给字典添加条目的操作,下面是两个示例说明。 使用键值对进行添加 通过在字典名称后面使用方括号、添加新键和相应的值来创建新的键值对,实现给字典添加条目。 >>> my_dict = {‘name’: ‘John’,…

    python 2023年5月13日
    00
  • python实现支付宝当面付(扫码支付)功能

    当面付是支付宝的一种扫码支付方式,即商家通过支付宝开放平台API接口生成一个二维码,顾客使用支付宝扫描该二维码进行支付。下面将详细介绍如何使用Python实现支付宝当面付功能。 1. 申请开发者账号 首先需要去支付宝开放平台官网申请开发者账号,并且创建应用获取app_id和支付宝公钥、私钥等信息。在创建应用时需要选择当面付功能作为接口权限。 2. 安装依赖库…

    python 2023年6月3日
    00
  • Python 数据可视化之Bokeh详解

    Python数据可视化之Bokeh详解 Bokeh是一个Python数据可视化库,它可以创建交互式的、现代化的、浏览器友好的图表。Bokeh支持多种图表类型,包括折线图、散点图、柱状图、热力图等。本文将详细讲解如何使用Bokeh进行数据可视化。 安装Bokeh 在使用Bokeh之前,需要先安装它。可以使用pip命令来安装Bokeh,命令如下: pip ins…

    python 2023年5月15日
    00
  • 在Python中把赫米特数列转换为多项式

    将赫米特数列转换为多项式,需要使用Python中的NumPy库和SymPy库。以下是详细步骤: 导入必要的库 首先,需要导入NumPy和SymPy库: import numpy as np from sympy import * 定义赫米特数列 赫米特数列是一个递推序列,可以使用递推公式来生成。SymPy库中已经内置了赫米特数列的递推公式,可以直接使用: n…

    python-answer 2023年3月25日
    00
  • 有没有办法从python中的调用函数访问变量?

    【问题标题】:Is there a way to access a variable from a calling function in python?有没有办法从python中的调用函数访问变量? 【发布时间】:2023-04-01 11:24:01 【问题描述】: 我不确定这是否可行,但我想知道是否有办法从外部范围获取变量而不将其作为参数传递。 我玩过…

    Python开发 2023年4月8日
    00
合作推广
合作推广
分享本页
返回顶部