KMP 算法

模式串和主串进行比较,当主串的第 i 个字符和模式串的第 j 个字符比较不同时,i 不用动,j 向前滑动到 k 即可。
当务之急是是找到,最大的 k,使得 pattern[0: k] == pattern[j-1-k: j-1],那么当匹配失败时,模式串 j 重置为 k 继续比较即可。

同时要注意,k < j,next[0] = -1(当第一个不匹配,特殊行为,i++, j++)

def get_next(pattn):
    """
    获取模式串的 next 数组,和平常所见处理不同,多一
    next[i] < i
    当模式串第 j 个字符和主串第 i 个字符不匹配时:
    1. 若 next[j] == -1, i += 1, j += 1
    2. 否则 j = next[j] 继续比较
    """
    N = len(pattn)
    next_i = [0 for _ in range(N)]
    # 当字符 0 不匹配,行为特殊,需要 i++ j++
    # 只要字符 1 不匹配,都得从字符 0 开始比较
    next_i[0:2] = [-1, 0]
    k = 0
    i = 2
    while(i < N):
        # 找出最大的 k (k<i) 使得 pattn[0:k-1] == pattn[i-k:i-1]
        if k == -1:
            # 3. 说明已经比较到了 pattn[0] != pattn[i-1]
            # 即没有相等的
            # 分支能够合并,但为了思路清晰,分开写
            k += 1  # 将 k 重置为 0
            next_i[i] = 0
            i += 1
            continue
        if pattn[k] == pattn[i-1]:
            # 1.
            k += 1
            next_i[i] = k
            i += 1
        else:
            # 2. 这其实也是一个模式串匹配的问题
            # 模式串 pattn[0:k],主串 pattn[i-k:i-1]
            # 当匹配失败时,模式串跳转到 next[k] 即可
            k = next_i[k]
    return next_i

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值