DFA到等價正則表達式的轉化


思考題的引入

首先看這樣一道思考題:

如何用正則表達式識別所有是三的倍數的二進制串?

考慮最暴力的做法。用一個變量rem表示一個串的前綴作為二進制對3的余數,對新進來的字符討論:

  1. 進來一個0,則rem=(rem<<1)%3;,因為我們是從高位向低位讀的
  2. 進來一個1,則rem=((rem<<1)+1)%3

那么只需要判斷最終rem是否為0就好了

自動機的做法

在做這題之前,可以先想想這樣的一個問題:

如何用自動機識別所有是三的倍數的二進制串?

或者說

如何用自動機表示上述暴力做法?

注意到rem的取值只能為0,1,2,因此可以建3個點,每個點兩條出邊表示對不同字符的處理轉移,那么建出來的圖如下

image

其中節點1,2,3分別表示rem對應為0,1,2的狀態。

"但是問題還沒完啊,你不是要正則表達式嗎"
做到這一點需要一些前置姿勢

正則表達式代數

沒錯!正則表達式也是有代數結構的!
為了方便,我們規定連接運算(concatenation)用.符號表示

符號 性質
| 結合律,交換律,對.的分配率
. 結合律
^ 冪等律

它們的優先級從上到下遞增

那么自然應該想到,列出正則表達式的代數方程,也是可以解方程的

Arden's Theorem

定理的內容很簡單,即對於形如 \(x=A|xB\) 的方程,\(x\) 的解都是 \(AB^*\) 的形式

對解的長度進行歸納。當 \(n=1\)\(x_1=A\) 是原方程的一個解,滿足 \(x=AB^*\) 的形式
設當 \(n<k\) 時成立,則 \(x_{n-1}=A\overbrace{B\ldots B}^{n-1\text{個}B}\),帶入方程右側就有 \(x_n=x_{n-1}B=A\overbrace{B\ldots B}^{n\text{個}B}\)
由數學歸納法可知原方程的解都是 \(x=AB^*\) 的形式,並且容易驗證形如 \(AB^*\) 的串都是方程的解。

類似的也有對 \(x=A|Bx\) 的結論

自動機到正則表達式的轉換

我們知道,自動機的每個狀態都對應着一個接受串的集合(從初始狀態到當前狀態所有路徑組成的串的並),而不同狀態之間存在轉移關系

那么就可以設未知數列方程辣!

對於最開始的那個DFA,我們可以設它的三個狀態對應的接受串的正則表達式為\(x_0,x_1,x_2\),那么有如下關系

\[\begin{cases} x_0 &=& x_00|x_11 \\ x_1 &=& x_01|x_20 \\ x_2 &=& x_10|x_21 \\ \end{cases} \]

對式3用Arden's Theorem得到\(x_2=x_101^*\)
代入式2得到 \(x_1=x_01|x_101^*0=x_01(01^*0)^*\)
代入式1得到 \(x_0=x_00|x_01(01^*0)^*=x_0(0|1(01^*0)^*)=(0|1(01^*0)^*)^*\)

於是就得到了與該自動機等價的正則表達式

需要注意的是,在這個表達式中,我們認為可以有任意的前綴零,並且空串和任意長度的0串都是3的倍數

升華一下

如果你樂於思考,就會發現我們上述"消元"過程意味着什么——我們在化簡自動機的狀態!
也就是說,假如我們要求得表示DFA從起點到終點e的串的集合的正則表達式,那么我們只需要合並掉除起點和e以外的所有狀態即可。


免責聲明!

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



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