字符串的模式匹配——Brute-Force算法和KMP算法


  子串的定位操作是要在主串S中找出一個與子串T相同的子串,通常把主串S稱為目標,把子串T稱為模式
把從目標S中查找模式為T的子串的過程稱為“模式匹配”。


1.Brute-Force算法的設計思想
  Brute-Force是普通的模式匹配算法。將主串S的第1個字符和模式T的第1個字符比較,若相等,繼續逐個比較后續字符;若不等,從主串的下一字符起,重新與模式的第一個字符比較,直到主串的一個連續子串字符序列與模式相等 ,返回值為S中與T匹配的子序列第一個字符的序號,即匹配成功;否則,匹配失敗,返回值 0。

def index(text,tgt_str):
    j=0
    tgt_len=len(tgt_str)
    for i in range(len(text)):
        if( text[i] == tgt_str[j] ):
            j+=1  
        else:
            i=i-j+1
            j=0
        if(j==tgt_len):
            return i-tgt_len+1
    return 0

2.Brute-Force算法的特點:
  每次遇到匹配不成功的情況,指針i都要移到本次匹配的開始位置的下一位,稱這樣的指針移動為回溯
  指針的回溯越多,簡單模式匹配的執行次數越多

Brute-Force匹配算法的最壞時間復雜度為 O(n*m)
一般情況下BF算法的時間復雜度為O(n+m)

 

3.KMP算法的改進
  每當一趟匹配過程中出現字符比較不等時,不需回溯指針i,而是利用已經得到的“部分匹配”的結果將模式向右“滑動”盡可能遠的一段距離后,繼續比較
  KMP算法的時間復雜度可以達到O(m+n)

4.KMP算法的設計思想

  假設以指針 i 和 j 分別指示主串和模式中正待比較的字符,令 i 的初值為0,j 的初值為0
  若在匹配過程中,Si=Pj,則i和j分別增1,否則i不變,而j退到next[j]的位置再比較,若相等,則指針各自增1,否則j再退到下一個next值的位置,依次類推


若令next[j]=k,則next[j]表明當模式中第j個字符與主串中相應字符失配時,在模式中需重新和主串中該字符進行比較的字符的位置
模式串的next函數定義為
    

      

 

 

#coding=utf-8
str1='9AA8'
text='8149AA86A5482A12958509AA8'
nextList=[0]

def get_next(tgt_str):
    i=1;j=0
    global nextList
    while(i < len(tgt_str)):
        if(j == 0 or tgt_str[i-1]==tgt_str[j-1]):
            i+=1;j+=1
            nextList.append(j)
        else:
            j=nextList[j-1]
    return nextList

def Index_KMP(text,tgt_str):
    j=0
    a=len(text)
    b=len(tgt_str)
    for i in range(a):
        while j>0 and text[i]!=tgt_str[j]:
            j=nextList[j-1]         #模式串向右移動
        if( text[i] == tgt_str[j] ):
            j+=1
        if j==b:
            print 'success'
            print 'location: '+str(i-b+1)
            j = nextList[j-1]
    else:
        print 'no match'

get_next(str1)
print nextList
Index_KMP(text,str1)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM