KMP next

KMP next数据mark

看了好多遍的next数组,还是不清楚,简单mark一下

  • next数组计算的是当前字符前面的字符串的最长匹配头和尾
  • next[0]=-1
  • next[[1]]=-1
def get_next(needle):
    n_len = len(needle)
    next = [0 for i in range(n_len)]
    j = -1
    i = 0
    next[i] = -1
    while i < n_len - 1:
        if j == -1 or needle[i] == needle[j]:
            j += 1
            i += 1
            next[i] = j
        else:
            j = next[j]
    return next

以aaabaabab为例说明next计算过程

  1. 如上数组所述,needle为需要计算next的数组,首先初始化next[0]=-1,一开始j==1进入循环,j = 0, i = 1,next[1] = 0,
    当i下标移动到1,j为0时,此时需要计算next[2]的值,比较位置为2的字符前面的字符串的最大头和尾,比较needle[1] 是否等于needle[0],等于,则i = 2, j = 1, next[2] = 1。
  2. 然后计算next[3],判断位置为3的字符前面的字符串的最大公共头和尾,此时已经计算得到位置为2的字符的前面的字符串的最大公共头和尾,则我们将上一步的得到的头和尾分别向后移动一步,看是否相同,即上一步的i+=1 和j+=1,可以想象,此操作就是对前一步的得到的头和尾分别再加一个字符串判断是否相等,next[2] = 1, 则此时比较needle[2] == needle[1]吗?等于,则 j += 1, i += 1, next[3]=2,(这时候我们可以看到,needle[3](字符b)前面的aa和从头开始的aa是相同的,即是最长的公共头和尾)
  3. 此时 i = 3, j = 2, 进入下一次循环,此时先判断上一步得到的最长头和尾分别在加一个字符是否相同,发现不是,此时保证当前i位置不变(此时的i即为下一步要计算的next的前面字符串的最后一位),将j返回到next[j]匹配的最大头处,即j = next[j] = next[2] = 1, 然后比较needle[3] == needl[1]吗?不等于 则j继续前移, j = next[1] = 0, 此时比较needle[3] == needle[0]吗?不等于,则j继续前移, j = next[0] = -1, 此时已无前缀字符串,则j+=1, i+=1, next[4] = 0
  4. 此时我们得到的是next[0]=-1, next[1]=0 next[2]=1, next[3]=2, next[4] = 0,此时 i = 4, j = 0, 判断needle[4] == needle[0]吗?等于,则 i+=1 j += 1, next[5] = 1
  5. 此时 i = 5, j = 1, 判断needle[5] == needle[1]吗?等于,则 i+=1 j += 1, next[6] = 2,此时得到的是next[0]=-1, next[1]=0 next[2]=1, next[3]=2, next[4] = 0,next[5] = 1,next[6] = 2
  6. ……
  7. 依次执行比较,最后得到的是next = [-1, 0, 1, 2, 0, 1, 2, 0, 1]

最后的核心原理还是判断当前字符前面的字符串的最长公共头和尾

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值