KMP算法

简介

一种用于字符串匹配的快速算法。该算法的核心在于利用已经匹配过的信息,避免不必要的字符比较,从而提高匹配效率。其中的一个关键部分是计算next数组,它用于指示在匹配失败时,应该将模式串向右移动多少位。

关键的next 数组怎么计算的?

下面是计算next数组的基本步骤:

  1. 初始化:将next数组的第一个元素(next[0])设为-1,将next数组的第二个元素(next[1])设为0。

  2. 遍历模式串:从模式串的第二个字符(下标为1)开始,依次计算每个位置上的next值。

  3. 计算next值:对于位置i,从i-1位置开始向前找,找到第一个与模式串第i个字符相等的位置j。然后,next[i]的值为j+1。

  4. 如果找不到这样的j,说明在当前位置i匹配失败时,应该将模式串整体向右移动一位,即next[i]为0。
    如果找到了j,说明在当前位置i匹配失败时,可以利用已匹配的信息,将模式串右移j+1位。
    重复:继续遍历模式串的下一个位置,重复步骤3,直到计算完整个next数组。

下面是一个示例,说明如何计算next数组:

"ABABCD" 

初始化:将next数组的第一个元素(next[0])设为-1,将next数组的第二个元素(next[1])设为0。

  A B A B C D
-1 0

对于位置1(B),[没找到与B相同的],所以 next[2] = 0 。

  A B A B C D
-1 0 0

对于位置2(A),找到位置0(A),所以 next[3] = 0+1=1。

  A B A B C D
-1 0 0 1

对于位置3(B),找到位置1(B),所以 next[4] = 1+1=2。

  A B A B C D
-1 0 0 1 2

对于位置4(C),没找到相同的,所以 next[5] = 0。

  A B A B C D
-1 0 0 1 2 0

在这里插入图片描述

def compute_next(pattern):
    """
    计算模式串的next数组
    """
    m = len(pattern)
    next_array = [-1] * m
    j = -1

    for i in range(1, m):
        while j >= 0 and pattern[i - 1] != pattern[j]: # 没有走到 -1 就是数组的头部,且不相等
            j = next_array[j]
        j += 1
        next_array[i] = j

    return next_array

def kmp_search(text, pattern):
    """
    KMP算法进行字符串匹配
    """
    n = len(text)
    m = len(pattern)
    next_array = compute_next(pattern)
    print("next数组:",next_array)
    i = j = 0

    while i < n: # 匹配是否到text末尾
        while j >= 0 and text[i] != pattern[j]: #
            j = next_array[j]
        i += 1
        j += 1

        if j == m:
            # 匹配成功,返回匹配位置的起始索引
            return i - j

    # 没有匹配成功,返回-1
    return -1

# 测试
text = "ABABCABABCABCABABCD"
pattern = "ABABCD"

result = kmp_search(text, pattern)

if result != -1:
    print(f"在文本中找到模式串,起始位置为:{result}")
else:
    print("在文本中未找到模式串")
  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值