KMP简介

关于啥是KMP 算法,还是去看大神的博客吧,他实在是写的太好了
阮一峰——字符串匹配的KMP算法
膜归膜,但是他所说的部分匹配表中的下标和各大参考书都格格不入。
为了应试需求,还是改成了我理解上的next数组(我们的教科书上叫这玩意儿失效函数,都是一个东西)。

KMP算法——NEXT数组

这是一道作业题:
求S=“abcaabbabcabaacbacba”失效函数的值
[-1, 0, 0, 0, 1, 1, 2, 0, 1, 2, 3, 4, 2, 1, 1, 0, 0, 1, 0, 0]
当然,这个太长了,不方便我们阐释
命S=“ abcdabcy”
那么失效函数,如果要手写的话,第一个肯定是“-1”<阮一峰里面写的就不是这样>
然后,abcd一定都是-1000,第二个a出现,这时候是0,之后的bc就是12,y则对应3。
就有了 [-1, 0, 0, 0, 0, 1, 2, 3]

那么如果用程序实现呢?

def pipeizhi(p):
    # abcdabcy
    # next函数偏移表next[]:-1    0    0    0    0    1    2    3
    j = 0
    k = -1
    next = [-1]
    for i in range(1, len(p)):
        next.append(0) # 先指定一个next数组为[-1,0,0,0...]
    try:
        while (j < len(p) - 1):
            if k == -1 or p[j] == p[k]: 
   # 如果找到了,那就开始滑动。j 遍历的事数组下标,而k则是为偏离表赋值的。画个图可能更加好理解
                j += 1
                k += 1
                next[j] = k
            else:
                k = next[k]
    except IndexError:
        print next, k, j  # 不可能错的放心
    return next

KMP 算法的实现

现在,有了next数组,就可以为所欲为了:

def KMP(s, t): #s是目标船 ,t是模式串
    slen = len(s)
    tlen = len(t)
    if slen >= tlen:
        i = 0
        j = 0
        next = pipeizhi(t)
       # print next
        while i < slen: #开始遍历
            print [i,j]
            if j == -1 or s[i] == t[j]: 
       #i是遍历,j是目标串中找到的模式串中前面一部分的长度。
                i += 1
                j += 1
            else:
                j = next[j]
            if j == tlen:
                return i - tlen
    return -1 #-1就是没有找到啊