字串匹配:從尾碼自動機到KMP

來源:互聯網
上載者:User

標籤:字串   演算法   

尾碼自動機(sam)上的字串匹配
====
我們把相對較短的模式串構造成sam。
對於P="abcabcacab", T[1..i]的尾碼,使得它是sam的最長前置長度:
T: b a b c b a b c a b c a a b c a b c a b c a c a b  c
   1 1 2 3 1 1 2 3 4 5 6 7 1 2 3 4 5 6 7 5 6 7 8 9 10 4
如果最長前置長度是|P|,則表示T[1..i]的尾碼和P匹配。


記憶體使用量
可能多個trans指標同一個節點,因此像刪除樹那樣會引起double-free:
為此我們暫時採用記憶體池的做法。
如果擴充到包括數字和空格,則需要表示37個轉移指標。


KMP演算法
====
給定模式串P,文本串T,
假設在s位置已匹配了q個字元, 即P[1,..,q]=T[s+1,..,s+q], 而在P[q+1]不匹配。
strstr()這時會把指標指向s+2,從P[1]重新開始匹配。
當時Knuth,Morris,Pratt就想可不可以把指標再移遠一點。
假設有P[1,..,k]=T[s+q+1-k,..,s+q],這時從P[k+1]開始比就行了,顯然我們希望k越大越好,對應地指標移動增量=q-k越小,因此應該不會錯過某些完全符合的位置。
我們把上面兩個等式合并,得到P[1,..,k]是P[1,..,q]的尾碼。問題變成:
對於每個q, 求P[1,..,q]的最長的真首碼(長度記為k),同時它也是P[1,..,q]的尾碼。
我們定義首碼函數pi(q):=k.


如何計算pi(q) ?
====
使用遞推的想法,假設我們已經計算好了pi(q)=k。
如果P[k+1] = P[q+1], 則顯然有pi(q+1) = k+1;
否則,看作是一個匹配問題, 我們來看pi(q)的含義是與P[1,..,q]末尾匹配的最長前置長度k,我們就拿這個首碼來匹配,並期望P[k+1]和P[q+1]一樣,否則k=pi(k)迴圈下去。
初始條件:pi(1) = 0, 因為最長真首碼是空串。


當前P[1,..,k]匹配T[q-k+1,q],而在T[q+1]不匹配,
應用首碼函數的定義,應該從位置s+1-k + q-k = 
一個字串P[1,..,j]去匹配P[q+1-j,..q+1]的過程。
k=pi(k), 直到P[k] = P[q+1]。


如何做線性字串匹配?
====
參照尾碼自動機的做法, 我們把pi和P組成一個自動機,T在這個自動機上
走一遍。


首碼函數練習題目:
1. P 在T中的出現次數? 提示:檢查pi(PT)
2. (ab)^3 = ababab, 如何求最大的重複因子r=3?

3. 如何線上性時間內判斷是否為迴圈移位,比如arc和car。(這個我還不知道怎麼做)



KMP比SAM節省記憶體:





聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.