KMP注记

相关介绍在下面:

  1. https://blog.csdn.net/yutianzuijin/article/details/11954939
  2. http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html
    实际上,最先看的是2,但并描述没那么清晰,1上的图描述易于理解。这里保存一下。注释见图注。
Fig 1. `O`是待搜索串,`f`是模式串。如果在`i`处没有匹配上,可以已知在该处之前有一定长度的后缀与O对应上(就是B段),所以如果有`next`表的协助,可以知道将f后移多少(就是*k*),能够匹配上这段后缀对应上O的字段。
要求next保存最长后缀,是避免回溯的关键环节(比如,考虑一下next中元素始终为0(除首个),那么每次*j*重置后依然不能匹配到*i*上,算法直接失败)。 关于对*f*进行移动这点,是`1`中没有表达的,但这一点更易于理解(好吧大佬们,对我而言(⊙﹏⊙)b)。
def genNext(s, nextTab=None, idx=0):
    assert idx>=0, idx
    if nextTab is None:
        nextTab = [0 for i in s]
    if idx==len(nextTab):
        return nextTab
    if idx ==0:
        nextTab[idx] = -1
    # fill the idx-th element...
    else:
        if s[nextTab[idx-1]+1] == s[idx]:
            nextTab[idx] = nextTab[idx-1] +1
        else:
            nextTab[idx] = 0
    return genNext(s,nextTab, idx+1)

s='ababcababa'
p='ababa'

print s
print p
print genNext(p)



def searchPat(s,p):
    nextTab = genNext(p)
    j=0
    i=0
    while True:
        if s[i]==p[j]:
            j+=1
            i+=1
        elif nextTab[j] >=0:
            j=nextTab[j]
        elif nextTab[j]==-1:
            i += 1
            j = 0
#        print i,j
        if j==len(p):
            return i-j
    return -1
print searchPat(s,p)
原文地址:https://www.cnblogs.com/chenyliang/p/8658637.html