閱讀960 返回首頁    go 小米 go 小米6


技海無涯:正則表達式相關的知識和技術(4)——自動機(完結篇)

自動機

自動機,顧名思義,就是能夠自動完成事情的“機器”。但是為什麼要用自動機,什麼又叫“自動”呢?

我們看看普通的處理方式,簡單的就是if了,例如:判斷某字符串是否是“Hello,Word,我們都會這麼寫:

ifstr == “Hello,Word”

普通的比較可以滿足大部分的場景,但對於正則表達式這種比較的話,普通的if就完全不能滿足了,例如a*b|c,可以是如下字符串:

ab

aab

aaaab

c

………….

這種情況我們不可能采用普通的if來判斷了,因為不可能窮舉所有的字符串。所以我們要另辟蹊徑,自動機就應運而生了。

我們這裏講的自動機有兩個:一個是確定有限自動機,又叫DFA;一個叫不確定有限自動機,又叫NFA。由於自動機的核心就是通過“狀態”和“狀態變遷”實現的,所以自動機又叫狀態機。

1) NFA

為什麼叫不確定自動機呢?就是因為存在“不確定性”了。

什麼不確定呢?就是一個輸入可能對應多個狀態轉換,所以就不確定了。

通過NFA來識別字符串的過程很簡單,即每輸入一個字符,都判斷當前的狀態集中哪些狀態上有此字符的轉換,然後把所有轉換後的狀態又記錄下來,依此循環,直到字符輸入結束或者狀態機結束。

不知道大家有沒有發現,NFA的識別過程其實非常類似NFA轉換到DFA的子集構造算法的過程。如下圖:

NFA識別過程,假如識別aabb

1)初始狀態:01247

2)輸入a,轉換到如右的狀態:3, 6, 7, 1 , 2 ,4,

3)輸入a,轉換到如右的狀態:8, 3, 6 , 7, 1, 2, 4

4)輸入b,轉換到如右的狀態:9, 5, 6, 7, 1, 2, 4

5)輸入b,轉換到如右的狀態:10, 5, 6, 7, 1, 2, 4

由於此時已經沒有輸入字符了,而且最終狀態10也包含進來了,因此aabb就接受了。

 

NFA->DFA的子集構造算法:

1)初始狀態:01247(第一個子集)

2)輸入a,轉換到如右的狀態:3, 6, 7, 1 , 2 ,4(第二個子集)

3)輸入a,轉換到如右的狀態:8, 3, 6 , 7, 1, 2, 4(第三個子集)

………………………..(依次類推)…………………………………………..

 

 

2) DFA.

介紹到這裏,相信大家都已經明白DFA的概念了。

所謂確定,就是指一個輸入隻能對應一個轉換。

DFA來識別字符串就更簡單了,由於轉換是確定的,所以直接將輸入字符輸入進行轉換即可。

 

3) NFADFA比較.

複雜度:當然是DFA高了;

速度:當然是DFA快了

 

到這裏正則表達式係列相關知識也就結束了,當然我在這裏知識提綱挈領,讓大家能夠從整體上把握這些相關的東東,不至於上來就被一堆術語和名詞弄暈了,同時也把關鍵的地方點了一下,希望能夠起到讓大家茅塞頓開的效果。

當然更加詳細和深入的研究還需要各位自己深入鑽研了,推薦《編譯原理(龍書)》和《精通正則表達式》兩本書。

 

最後更新:2017-04-02 03:13:28

  上一篇:go NanoXML組件解析xml簡單例子
  下一篇:go Jdom讀xml解析實例子