kmp算法理解与实现

kmp算法主要目的是减少逐个检索,将搜索内容右移由诸逐个变成可能多个移动。
abababadababacambabacaddababacasdsd
ababaca
0ababaca(遍历的搜索下一步应该是)
00ababaca(而kmp算法应该是)
原因:
kmp算法是在遍历时找上下第一次不同的情况,这个例子就是第5位(6)。
我们再对下面的前5个字符找他们的最长公共前后缀。
对于ababa,4个字符时abab和baba不相同,3个字符时aba和aba相同所以最长公共前后缀为3。
我们就可以将ababa从相对前缀的位置移动到公共后缀的位置,移动的距离就是len(‘ababa’)-3。
这样就实现了kmp算法的多个移动。

由上面的原理我们需要找到ababaca每个位置的最长公共前后缀即获得next列表。
第0位:‘a’,无公共前后缀,最长公共前后缀是0
第1位:‘ab’,1个字符时a和b不相同,最长公共前后缀是0
第2位:‘aba’,2个字符时ab和ba不相同,1个字符时a和a相同,最长公共前后缀是1

第6位:‘ababaca’,6个字符时ababac和babaca不相同,…,1个字符时a和a相同,最长公共前后缀是1
next = [0,0,1,2,3,0,1]。

代码实现:

def zuichangqianhouzhui(strs):
    next = []
    for i in range(len(strs)):
        z = i
        if z == 0:#0是特例不存在公共前后缀,所以一定是0
            next.append(0)
        else:
            while z <= i:
                if strs[:z] == strs[:i+1][len(strs[:i+1]) - z:]:
                #暴力比较,从最多(len(strs)-1)逐个比较是否可行
                    b = z
                    next.append(b)
                    break
                else:
                    z = z - 1
    return next

下面我们继续通过代码实现整个查找功能:

def kmp(str_long,str_short):
	#str_long是被查找内容,str_short是查找内容
    next = zuichangqianhouzhui(str_short)#获得next列表
    i = 0#查找内容开始匹配被查找内容的位置
    z = 0#找到查找内容的次数
    while i < len(str_long)-len(str_short):#当开始匹配的位置到被查找内容结尾的长度比查找内容短时已经不可能找到
        a = i#从开始匹配位置进行逐个字母匹配,被查找内容上的指针
        #如从第8位开始匹配,a=8,应该时用str_long[8]和str_short[0]进行比较
        for i1 in range(len(str_short)):#对查找内容逐个匹配
            if str_long[a] == str_short[i1]:#如果相同继续匹配下一位
                a = a + 1
                if (a-i) == len(str_short):#如果一直匹配到查找内容的最后一位都是一样,那就是找到了这个内容。记录次数,并i移到一下位继续匹配
                    z = z + 1
                    i = i + 1
                    break
            else:
                if i1 == 0:
                #如果在进行第一位匹配时就不一样,那也用要next里面找移动位,i直接右移一位。
                    i = i + 1
                else:
                #如果在后面找到不一样的,i就右移[len('ababa')-3(接上面的例子)]
                #对应下式len('ababa')就是a-i,也就是匹配中前端完全相同的长度。
                #next[a - i - 1]就是3,也就是第a - i - 1位最长公共前后缀的长度。
                    i = i + a - i - next[a - i - 1]
                break
    return z

这只是我个人对kmp算法的理解与实现,欢迎大家讨论,指出我理解不对的地方

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值