簡體   English   中英

具有有限自動機的字符串匹配

[英]string matching with finite automata

我正在閱讀Cormen的書“算法導論”中的字符串算法。 對於過渡,如下所示。

我的問題:為什么我們要做min(m+1, q+2) ,為什么我們要m遞增1,q遞增2。

以下鏈接有上述問題。

http://people.scs.carleton.ca/~maheshwa/courses/5703COMP/Fall2009/StringMatching.pdf

請幫助一個簡單的例子。

Algorithm Compute-Transition-Function(P, Sigma)
m = length(P);
for  q = 0 through m  do
   for each character  x  in Sigma
       k = min(m+1, q+2);
       repeat  k = k-1  // work backwards from q+1
       until  Pk 'is-suffix-of' Pqx;
       d(q, x) = k; // assign transition table
   end for;
end for;

return  d;
End algorithm.
  • 它是m + 1因為在下一個repeat循環中, k首先減小。
  • 這是q + 2因為在repeat你開始然后用q + 1所以至少有1個字符。

以下代碼可能存在邊界問題(q == m丟失),但希望使索引更清晰。

m = length(P);
for  q = 0 through m - 1 do // Loop through substrings [0, q+1]
   for each character  x  in Sigma
       k = q+1;
       // work backwards from q+1
       while not Pk 'is-suffix-of' Pqx;
       do k = k-1; end do;
       d(q, x) = k; // assign transition table
   end for;
end for;

return  d;

代碼已被解釋,所以這里是一個例子來看看發生了什么

假設字符串是nan​​o

所以我們希望我們的狀態與模式部分匹配。 "nano"部分匹配可能是"", "n", "na", "nan", or (the complete match) "nano"本身。 換句話說,它們只是字符串的前綴。 一般來說,如果模式有m個字符,我們需要m + 1個狀態; 這里m = 4,有五個州。

如果我們剛看到"...nan" ,看到另一個字符"x" ,我們應該去哪個州? 顯然,如果x是匹配中的下一個字符(這里是“o”),我們應該轉到下一個更長的前綴(這里是“nano”)。 很明顯,一旦我們看到完全匹配,我們就會保持這種狀態。 但是假設我們看到一個不同的角色,比如"a" 這意味着到目前為止,字符串看起來像"...nana" 我們可能會遇到的最長的部分匹配只是"na" ,即我們可以利用最后2個字符。 因此,從狀態"nan" ,我們應繪制一個標記為"a"的箭頭,將狀態為"na" 請注意, "na""nano" (因此是狀態)的前綴,並且是"nana"的后綴(因此是與我們剛剛看到的部分匹配的部分)。

通常,從狀態+字符到狀態的過渡是最長的字符串,它同時是原始模式的前綴和我們剛剛看到的狀態+字符的后綴。 這足以告訴我們所有轉換應該是什么。 如果我們正在尋找模式"nano" ,那么過渡表就是

     n       a       o      other
    ---     ---     ---     ---
empty:  "n"     empty   empty   empty       
"n":    "n"     "na"    empty   empty
"na":   "nan"   empty   empty   empty   
"nan":  "n"     "na"    "nano"  empty    //just as an illustration, nan + n = n because we can only use the last 'n', nan + a = na because now we can use the last two 'na'
"nano": "nano"  "nano"  "nano"  "nano"

那么現在我們如何使用這個表來實際進行模式搜索?

在字符串"banananona"上模擬這個,我們得到狀態序列為空,空, "n", "na", "nan", "na", "nan", "nano", "nano", "nano"通過一次移動一個角色。 由於我們以狀態"nano"結束,因此該字符串在某處包含"nano" 所以讓我們來看看最新情況以及如何使用上面的表格,在'b',我們沒有任何可能的狀態'n', 'na', 'nan', 'nano' 所以它算得空了......就像我們到了'ba' 當我們打到下一個字符'n' ,基本上是從空到n,因此我們使用上面的表,並看到它以'n'結尾。 現在我們得到了banananona的4個角色,所以我們從'n'開始添加...再次我們使用該表並看到它最終處於'na'狀態,依此類推......

轉換表中的條目d(q,x)包含消耗字符x后模式的最長匹配前綴的長度,如果在消耗x之前,最長匹配前綴是q字符長。 因為我們消耗一個字母,所以它不能大於q+1 ,並且由於該模式具有長度m ,所以它也可以最多為m 內循環repeat k = k-1 until condition(k) ,因此在測試任何東西之前, k都會遞減,因此k必須以大於最大可能結果的1開始, k = min(m,q+1) + 1 如果內部循環是while negated_condition(k) { k = k-1; } while negated_condition(k) { k = k-1; } ,將從k = min(m,q+1)

注意,通過將邊界表用於Knuth-Morris-Pratt算法,可以更高效地計算轉換表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM