KMP算法(Python实现)

本篇文章是对Kmp用Python进行了实现。

1.时间复杂度分析

BF算法的时间复杂度:在最坏的情况下,BF算法要将目标串的每一个字符同模式串进行比较一遍,假定目标串长度为m,模式串长度为n,总的时间复杂度为O(m*n)。而对于KMP算法,进行比较的时间复杂度为O(m+n),求next数组的时间复杂度为n,总体时间复杂度为O(m+2n)。

2.源代码

源代码介绍:BF_Match为常规的模式匹配算法,KMP_Match_1和KMP_Match_2为KMP算法,二者是一样的,不同之处在于二者调用了不同的求Next数组的函数。求Next数组有两种方法:一种是递推法getNext_1(),一种是直接求取的方法getNext_2()。详情请参阅下面的源代码:

import random  
import datetime  

def BF_Match(s, t):  
    slen = len(s)  
    tlen = len(t)  
    if slen >= tlen:  
        for k in range(slen - tlen + 1):  
            i = k  
            j = 0  
            while i < slen and j < tlen and s[i] == t[j]:  
                i = i + 1  
                j = j + 1  
            if j == tlen:  
                return k  
            else:  
                continue  
    return -1  

def KMP_Match_1(s, t):  
    slen = len(s)  
    tlen = len(t)  
    if slen >= tlen:  
        i = 0  
        j = 0  
        next_list = [-2 for i in range(len(t))]  
        getNext_1(t, next_list)  
        #print next_list  
        while i < slen:  
            if j == -1 or s[i] == t[j]:  
                i = i + 1  
                j = j + 1  
            else:  
                j = next_list[j]  
            if(j == tlen):  
                return i - tlen  
    return -1  

def KMP_Match_2(s, t):  
    slen = len(s)  
    tlen = len(t)  
    if slen >= tlen:  
        i = 0  
        j = 0  
        next_list = [-2 for i in range(len(t))]  
        getNext_2(t, next_list)  
        #print next_list  
        while i < slen:  
            if j == -1 or s[i] == t[j]:  
                i = i + 1  
                j = j + 1  
            else:  
                j = next_list[j]  
            if j == tlen:  
                return i - tlen  
    return -1  

def getNext_1(t, next_list):  
    next_list[0] = -1  
    j = 0  
    k = -1  
    while j < len(t) - 1:  
        if k == -1 or t[j] == t[k]:  
            j = j + 1  
            k = k + 1  
            next_list[j] = k  
        else:  
            k = next_list[k]  

def getNext_2(t, next_list):  
    next_list[0] = -1  
    next_list[1] = 0  
    for i in range(2, len(t)):  
        tmp = i -1  
        for j in range(tmp, 0, -1):  
            if equals(t, i, j):  
                next_list[i] = j  
                break  
            next_list[i] = 0  

def equals(s, i, j):  
    k = 0  
    m = i - j  
    while k <= j - 1 and m <= i - 1:  
        if s[k] == s[m]:  
            k = k + 1  
            m = m + 1  
        else:  
            return False  
    return True  


def rand_str(length):  
    str_0 = []  
    for i in range(length):  
        str_0.append(random.choice("abcdefghijklmnopqrstuvwxyz"))  
    return str_0  

def main():  
    x = rand_str(20000)  
    y = rand_str(5)  

    print "The String X Length is : ", len(x), " String is :",  
    for i in range(len(x)):  
        print x[i],  
    print ""      
    print "The String Y Length is : ", len(y), " String is :",  
    for i in range(len(y)):  
        print y[i],  
    print ""      

    time_1 = datetime.datetime.now()  
    pos_1 = BF_Match(x, y)  
    time_2 = datetime.datetime.now()  
    print "pos_1 = ", pos_1  

    time_3 = datetime.datetime.now()  
    pos_2 = KMP_Match_1(x, y)  
    time_4 = datetime.datetime.now()  
    print "pos_2 = ", pos_2  

    time_5 = datetime.datetime.now()  
    pos_3 = KMP_Match_2(x, y)  
    time_6 = datetime.datetime.now()  
    print "pos_3 = ", pos_3  

    print "Function 1 spend ", time_2 - time_1  
    print "Function 2 spend ", time_4 - time_3  
    print "Function 3 spend ", time_6 - time_5  

main() 

原文地址:http://blog.csdn.net/u010189459/article/details/30067705

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值