Python3实现KMP字符串匹配算法详解

Ruby
Ruby
发布时间:2026-10-13 | 4人浏览过
原创

本文介绍Python3中KMP字符串匹配算法的实现。首先对比暴力匹配法的时间复杂度问题,引出KMP算法的核心优化:通过计算模式串的next数组(基于最大前后缀长度)来避免回溯。文章详细解析next值的计算逻辑,并提供完整的Python代码示例,帮助开发者理解并应用该算法。

首先说明,笔者技术尚浅,撰写博客旨在记录学习历程、梳理个人理解与心得。文中若有疏漏或不当之处,恳请高手批评指正。

问题提出

给定一个主文本串test_str(被匹配对象)和一个模式串pat_str(需要查找的子串),目标是从test_str中找出pat_str首次出现的起始位置;若未找到,则返回-1。

暴力匹配法

在介绍KMP算法之前,我们先回顾最原始的“暴力匹配”方法。

text_str = 'asdabcdace'
pat_str = 'abcdace'

def str_match(text_str,pat_str):
  for i in range(0,len(text_str)):
    j = 1
    while j < len(pat_str):
      if text_str[i:i+j] != pat_str[0:j]: #从text_str第i个字符开始,看匹配是否成功
        break  #匹配失败,直接跳出循环,i+1,继续从第一个字符匹配
      j += 1   #匹配成功就继续匹配下一个字符,知道pat_str每个字符都匹配完
    if j == len(pat_str):
      return i
  return -1

print(str_match(text_str,pat_str))

之所以称为暴力解法,是因为每次匹配失败后,模式串仅向后移动一位,并从主串的下一个字符重新开始匹配,如此循环直至结束。这种方法导致时间复杂度较高,而KMP算法正是针对这一低效环节进行优化,其核心在于利用每次匹配失败时计算出的next值来确定下一次移动的距离。

KMP算法

若要完全透彻讲解KMP算法颇具难度,此处仅粗略梳理其实现步骤。我认为理解该算法的关键在于一个核心点:

如何计算模式串中每个字符对应的next值。

由于每次匹配失败时已匹配的字符长度不同,导致下一次移动的距离也各不相同。因此,我们需要一种方法来求解每个字符对应的next值,这引出了另一个重要概念:

最大前缀与最大后缀。

    

假设最大前缀与最大后缀的长度相等,记为k,那么第i位字符对应的next值即为k+1。通过一次循环遍历,即可求出每个字符对应的next值。

代码实现

#求字符串的next值
text_str = 'asdabcdace'
pat_str = 'abcdace'

#得到字符对应的next值
def str_next(s):
  #前两个字符默认等于1
  next = [1,1]
  for x in range(2,len(s)):
    next.append(str_max_prx(s,x,next[x-1]-1) + 1)
  return next
#参数 s字符串,匹配进行到的位置,下次开始匹配的位置
def str_max_prx(s,x,last_value):
  next = 0
  for i in range(last_value,x):
    if s[0:i] == s[x-i:x]:
      next = i
  return next
def str_match(s,m):
  next = str_next(s)
  i=0
  s_len = len(s)
  m_len = len(m)
  while i <= m_len:
    flag = True   #标志位,用来判断是否匹配成功
    index = 1
    while index <= s_len:
      if m[i:i + index] != s[0:index]:
        i = i + next[index]
        flag = False
        break
      else:
        index += 1
    if flag:
      break
  if i >= m_len:
    i = -1
  return i
res = str_match(pat_str,text_str)
print(res)

具体代码逻辑如上,其中许多细节需要读者自行深入理解。此处仅作笔记以备日后查阅,希望能对各位有所帮助。也欢迎大家支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表