【Python】KMP算法

字符串查找问题

给定文本串text和模式串pattern,从文本串text中找出模式串pattern第一次出现的位置。

暴力求解算法

Python代码

# 暴力求解
def brute_force_search(ss, s):
    i = 0  # 当前匹配的原始字符串首位
    j = 0  # 模式串的匹配位置
    size = len(s)
    nlast = len(ss) - size
    while i <= nlast and j < size:
        if ss[i + j] == s[j]:  # 若匹配模式串位置后移
            j += 1
        else:  # 若不匹配,则对比下一个位置,模式串回溯到首位
            i += 1
            j = 0
    if j >= size:
        return i
    return -1

暴力求解的思路比较简单,这里就不在赘述。


KMP算法

当暴力求解不匹配的时候,每次都要再一次从模式串首位做匹配,如下图, x ! = y 时,每次右移1位,然后从头比较:
暴力求解

其实虚线中的移动都是多余的,直接移动到c所在的位置,比较c和x是否相等就可以了。所以关键是怎么在y求c所在的位置。观察模式串:
这里写图片描述
c 所在的位置就是 y 前面的字符串的最大相同前缀(ab)和后缀(ab)的数量 2 ,令 y 的next为2。
如果能把所有位置的next值都能够求出来,比较的时候,当字符不匹配时,模式串直接移动到next标识的位置,然后继续比较就可以了。这就是KMP算法。

求next就是求字符串的最大相等前缀和后缀
这里写图片描述
如:j=7时,考察字符串“abcdeab”的最大相等k前缀和k后缀:
这里写图片描述
字符串“abcdeab”的最大相等k前缀和k后缀是"ab",值为2。
计算 next[ j ] 时,考察的字符串是模式串的前 j - 1 个字符,求其中最大相等的前缀和后缀的数量,与 s[ j ] 无关

next的递推关系

这里写图片描述
对于模式串的位置 j,有next[ j ] = k,即:p0p1…pk-2pk-1 = pj-kpj-k+1…pj-2pj-1
则,对于模式串的位置j+1,考察p[ j ]:
若p[ k ]==p[ j ](两个黄色部分相等)
next[ j+1 ]=next[ j ]+1
这里写图片描述
若p[ k ]≠p[ j ](灰色部分和黄色部分不相等)
记h=next[ k ],如果p[ h ]==p[ j ](紫色部分和黄色部分相等),则next[j+1]=h+1,
否则重复此过程。

Python代码

# 计算next数组
def get_next(s):
    size = len(s)
    next 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值