看毛片算法 KMP

找最长匹配前缀。 

 

 

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()

 

转载于:https://my.oschina.net/u/1246109/blog/801537

<think>好的,我需要回答用户关于BF算法KMP算法的优缺点及使用场景的问题。首先,我需要回忆这两种算法的基本概念和工作原理。BF算法,即暴力匹配算法,是通过逐个比较主串和子串的字符来实现匹配的,如果发现不匹配,主串就回溯到开始位置的下一个字符,子串则从头开始。这种方法实现简单,但效率较低,尤其是在最坏情况下时间复杂度是O(n*m),其中n和m分别是主串和子串的长度。 接下来是KMP算法,它的核心在于利用部分匹配表(next数组)来避免不必要的回溯。当发生不匹配时,子串不是每次都回到开头,而是根据next数组回退到某个位置,主串不需要回溯。这样可以减少比较次数,提高效率,时间复杂度为O(n+m)。 然后,我需要比较两者的优缺点。BF算法的优点是实现简单,逻辑清晰,适合小规模数据或匹配概率高的场景。缺点是效率低,特别是在处理大规模数据时,性能下降明显。而KMP算法的优点是高效,尤其是在处理有大量重复前缀或后缀的子串时,通过next数组优化了回溯过程。但它的实现相对复杂,需要预处理生成next数组,占用额外的空间。 应用场景方面,BF算法适用于子串较短、主串和子串匹配概率较高的情况,或者对实现复杂度有严格要求的场景。KMP算法则更适合处理大规模文本搜索,尤其是当子串有重复部分时,如DNA序列分析、编辑器中的查找功能等。 我还需要检查用户提供的引用内容,确保回答中的信息准确。引用中的代码示例展示了BF和KMP的实现,特别是KMP中next数组的生成和匹配过程。这有助于确认KMP算法的核心机制确实依赖于预处理步骤。 最后,生成相关问题时要围绕用户的需求,可能包括算法的时间复杂度分析、具体实现细节、优化方法等,确保问题有针对性且能帮助用户深入理解。</think>### BF算法 vs KMP算法 优缺点及使用场景 #### **一、核心差异对比** | **特性** | **BF算法** | **KMP算法** | |----------------|----------------------------------------|-----------------------------------------| | **时间复杂度** | 最坏$O(n \times m)$,平均$O(n+m)$ | 最坏$O(n + m)$,预处理时间$O(m)$[^1] | | **空间复杂度** | $O(1)$ | $O(m)$(需存储next数组)[^1] | | **核心逻辑** | 暴力逐个字符
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值