日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一.正则表达式转换为有限状态自动机:正则表达式转NFA

發(fā)布時間:2024/1/8 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一.正则表达式转换为有限状态自动机:正则表达式转NFA 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文:https://study.163.com/course/courseMain.htm?courseId=1002830012

一.有限狀態(tài)自動機的分類
有限狀態(tài)自動機,其實可以分成兩類。第一類是我們上面給出的,叫做確定性有限狀態(tài)自動機: Deterministic finite automaton 簡稱DFA. 確定性的狀態(tài)機有一個特點,就是給定當前狀態(tài)和輸入字符,那么下一個狀態(tài)就能被唯一確定。例如基于上圖,在狀態(tài)1時,接收到字符0-9,那下一個狀態(tài)一定只能是1,如果接收到字符 . ,那下一個狀態(tài),就一定只能是2. 更嚴謹?shù)恼f, DFA 是這樣一種自動機,從給定狀態(tài)出去的邊都對應著一個確定的字符,同時,從一個狀態(tài)出去的兩條邊,他們對應的字符必定是不同的。
對應于DFA, 另一種狀態(tài)機叫非確定性有限狀態(tài)機: Nondeterministic finite automaton, 即NFA. 在實踐中,要想順利的將正則表達式轉(zhuǎn)換為自動機,需要NFA的幫助。NFA 的特點是,從一個狀態(tài)出去的兩條邊,可以有相同的對應字符。或者它的邊可以對應一種特殊的字符叫”空”字符,該字符對應的符號是: ?. 這種邊表示,不需要任何輸入,就可以從當前狀態(tài)進入下一個狀態(tài)。
舉個例子,表達式(and | any) , 它對應的DFA如下:

從初始狀態(tài)開始,分化出兩條邊,兩條邊對應的字符是一樣的

或者:
從初始狀態(tài)分化兩條對應字符為空字符的邊,然后分別進入兩個對應的狀態(tài)機.

第二種NFA在程序設計中容易實現(xiàn),因此,在下一節(jié)的代碼中,我們將采用第二種NFA的實現(xiàn)模式。
NFA有一個明顯的弱點就是,在代碼設計中,很難用數(shù)據(jù)結(jié)構(gòu)來對它進行表示。特別是,當對應于一個輸入字符,NFA可以跳轉(zhuǎn)到多個狀態(tài),那么,要想利用NFA去識別輸入字符串就比較困難。一般而言,使用NFA的程序都需要經(jīng)過下兩個步驟:將正則表達式轉(zhuǎn)換為NFA, 將NFA轉(zhuǎn)換為DFA. 在后面的討論中,我們將通過代碼來展示這兩種轉(zhuǎn)換.

Thompson 構(gòu)造法:
將正則表達式轉(zhuǎn)換為NFA的算法是由貝爾實驗室的Ken Thompson 給出的,這哥們跟丹尼斯.里奇共同開發(fā)了Unix, 而他開發(fā)了C語言的前身 B 語言。
算法如下:
最簡單的正則表達式是單字符匹配,例如 a 匹配輸入字符”a”, 那么該表達式的NFA 構(gòu)造如下:

那么,兩個這樣的正則表達式合成的連接表達式ab 可以表示如下:

實際上,它是先分別構(gòu)造出兩個表達式的NFA, 然后通過一條?邊,將兩個NFA首尾連接起來。
下面我們看看,兩個表達式進行 OR 操作的時候 | ,NFA怎么構(gòu)造,構(gòu)造圖如下:

要構(gòu)造兩個表達式的或操作: exp1 | exp2, 根據(jù)圖示,首先分別構(gòu)造兩個表達式exp1 , exp2 各自的NFA: NFA1(上頭虛線框), NFA2(下頭虛線框), 然后再構(gòu)造兩個狀態(tài),初始狀態(tài)(開頭圓圈節(jié)點),和結(jié)束狀態(tài)(末尾圓圈節(jié)點),初始狀態(tài)延生處兩條 ? 邊,分別指向NFA1 和 NFA2 的開頭,然后NFA1 和 NFA2的結(jié)尾各自延生出一條?邊,分別共同指向結(jié)束狀態(tài)。

我們再看看 a | b 的NFA圖:

其原理跟前面所描述的是一樣的。上頭虛線框是表達式 a 的NFA, 下頭虛線框是表達式 b 的NFA. 兩個NFA的連接跟前面描述的一模一樣
如果表達式是( (a|b) | cd) 呢,算法也同理,先構(gòu)造 a | b 的NFA圖,然后構(gòu)造cd的NFA圖。最后根據(jù)前面所說的辦法,再將兩個NFA連接起來:
上頭大虛線框是 (a|d) 的NFA, 下頭長匾虛線框是 cd的NFA. 然后首尾通過兩個狀態(tài)節(jié)點和ε邊連接起來。

大家可以看到, Thompson構(gòu)造算法其實是一個自我遞歸的過程
我們再看看相應的閉包操作的構(gòu)造過程:
exp* 的NFA:
如果是自我從復0次,那直接從下面的邊走到末尾節(jié)點。

exp+(至少重復一次) 的NFA:

exp? (重復0或1次)的NFA:

任何復雜的正則表達式它的NFA的構(gòu)造都是上面幾種構(gòu)造的組合, 例如表達式
(D*.D | D.D*)
構(gòu)造算法如下:
1.構(gòu)造 D 的NFA:

2.構(gòu)造 D*(跟左邊的圖對應):

3.構(gòu)造 D*.D (由于.在正則表達式中是特殊字符,如果要僅僅想要表達它的符號內(nèi)容,要在前面加上反斜杠做轉(zhuǎn)義):
. 號的前部分是D*, 后部分是 D 的NFA.

4.構(gòu)造 D.D*, 該表達式的NFA其實就是將上圖 . 后面的部分挪到開頭。
5.根據(jù)OR 的構(gòu)造法, 構(gòu)造整個表達式 (D*.D | D.D*)的NFA:
上頭是 D*.D 的NFA, 下頭是 D.D*的NFA

再復雜的表達式的NFA的構(gòu)造,都是幾種基礎構(gòu)造的重復組合運用。

總結(jié)

以上是生活随笔為你收集整理的一.正则表达式转换为有限状态自动机:正则表达式转NFA的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。