pda與cfg之間的轉換
關於由pda向cfg的構造
pda與cfg的等價的,意味著對任意上下文無關文法(cfl),都相應地存在乙個pda接受它。而這個等價性證明對於大部分學生而言都是形式語言中能與圖靈機(turing machian)構造相提並論的絕對難點之一。而這其中最讓人難以理解的便是如何由pda轉換為相應的cfg。 「你可以先用兩周的時間開明白它是怎麼構造的,然後再花乙個月的時間,你就會逐漸理解它為什麼這麼構造。」 sdl講這部分內容的時候如是說。這是我寫這篇文章的動機。儘管下午兩小時形式語言考試的結束意味著至少在相當一段時間裡我不會再去研究相關的問題,可是在飽嘗口授之苦之後,我覺得依然有必要把我對這部分的理解寫下來,算是裨益後人吧。希望對看到它的人有所幫助。
首先是所構造的cfg中每個變元所表示的涵義:
形式:[qxp] 涵義:pda中的狀態q在pop(x)之後到達p狀態
生成式:以下將用例題來闡述生成式的構造方法以及其原理。
例:將pdap=(, , , δ, q, z)轉換為cfg,其中δ為:
1: δ(q, 1, z) =
2:δ(q, 1, x) =
3:δ(q, 0, x) =
4:δ(q, ε, x) =
5:δ(p, 1, x) =
6:δ(p, 0, z) =
ok,我們來開始構造:
令所要構造的cfgg=(v, t, p, s)
首先看p接受哪些串。顯然對它接受的串w, 都滿足由初始狀態(start state)讀入串w之後達到empty stack。細心的人可能會發現p是以空棧方式接受的pda,但聰明的人會更深一步去想,為什麼轉換成cfg的pda必須是以空棧方式接受的,而不能是以終態方式接受的?
好了,既然如此,那麼所構造的cfg應該有什麼樣的生成式呢?
很顯然:s -> [qzq] | [qzp]即每個生成式都是由pda中的初始狀態q通過一系列變換之後pop(z)的結果,至於終態是什麼,我們不知道,因為它是以空棧方式接受的,因此pda中存在多少個狀態,q將棧底元素pop之後就能到達多少個狀態。
接下來,我們將為每個轉移過程構造相應的生成式:
1: δ(q, 1, z) =
由於我們所構造的cfg中的變元形式為[qxp], 它的涵義在上面已經講過。而針對這個轉移並不是執行pop操作,而是執行push操作。那我們應該怎麼辦呢?這是整個轉換過程中最抽象的地方,也是最難理解的地方。 回想一下我們對start symbol的構造,我們最終是要將棧底元素z彈出,而這個過程我們可以將它劃分為n個子過程,即我們現在所看到的生成式。每個生成式都是乙個pop的過程,最終所有的pop過程迭加起來便得到最終的空棧狀態。這是為什麼針對push操作(包括其他任何操作)我們都構造pop形式變元的原因。
對於該轉移,我們得到的生成式是:
[qzq] -> 1[qxq][qzq]
[qzq] -> 1[qxp][pzq]
[qzp] -> 1[qxq][qzp]
[qzp] -> 1[qxp][pzp]
為什麼是這樣?
首先看->左邊的變元,顯然根據轉移δ(q, 1, z) = 我們知道這是乙個push操作,因此q在pop棧底元素z後我們不知道它會發生什麼,同樣的,它會轉移到什麼狀態對於我們而言也是完全透明的,因此我們必須考慮進所有情況。
而它因何會生成->右邊這種形式的生成式呢,我們來考慮乙個例子:
比如說郭先生想從哈爾濱去廣州看望故人,當然他可以選擇直接從哈爾濱飛往廣州,這也是最快的方法。而郭先生喜愛享受旅途的過程,於是他先從哈爾濱飛往大連,再由大連坐船至杭州,再由杭州乘火車至廣州。從邏輯上講(或者從形式上說)這兩種方法顯然是等價的。
好的,我們現在來考慮這個過程與我們所構造文法的內在關聯。
第乙個過程是郭先生直接從哈爾濱飛往廣州。對,這就是->左邊的變元涵義。由此說來右邊生成式的涵義也容易理解了,郭先生身上原有z元錢,從哈爾濱(狀態q)乘飛機(讀入1)至大連(狀態q),這個過程中他往銀行取了x元錢。再由大連坐船至杭州,花費x元錢([qxq]
),接著由杭州坐火車至廣州,花費z元錢([qzq]
),同時他的目的地也到達了。
想通了麼?是不是忽然發現這個過程有點簡單的匪夷所思?呵,everything is easy.
當然了,中間站是可以選擇的,因此從大連出發,我可以去杭州,也可以去天津,南京等其他城市。
有了這個描述過程,我想接下來的轉換可以不必再詳細解釋了。
2:δ(q, 1, x) =
它的生成式如下:
[qxq] -> 1[qxq][qxq]
[qxq] -> 1[qxp][pxq]
[qxp] -> 1[qxq][qxp]
[qxp] -> 1[qxp][pxp]
3:δ(q, 0, x) =
[qxq] -> 0[pxq]
[qxp] -> 0[pxp]
這裡會有疑惑?想想郭先生為什麼一定要途中經過兩個城市再到廣州呢?
明白了吧,我們繼續。
4:δ(q, ε, x) =
[qxq] -> e
這是乙個pop操作,因此不需要任何中介。
5:δ(p, 1, x) =
[pxp] -> 1
6:δ(p, 0, z) =
[pzq] -> 0[qzq]
[pzp] -> 0[qzp]
中文與ASCII之間的轉換
我們在開發使時常會用到資源檔案,這可能是為了多語言 國際化的需要,也可能是使用了國外開源專案的原因,這就需要將中文轉換為 ascii 編碼,或者將 ascii 轉換為中文,那麼我們就可以使用 jdk自帶的轉換工具 native2ascii for example no1 中文轉換為 ascii 編碼...
sring與Cstring之間的轉換
今天,主管找我談話。鬱悶 說我的 中的字串為何使用string而不用char 這樣會在應用層轉為cstring的時候產生不可 的錯誤。很奇怪,這是為何?string可是進入了c 標準的,難道c 標準委員會的大佬們在審查string類的時候都睡著了?無奈!上網!查。終於發現,cstring的特別之處。...
Bitmap 與 Drawable 之間的轉換
轉換bitmap to drawable bitmap bitmap new bitmap drawable drawable new bitmapdrawable bitmap 轉換drawable to bitmap drawable d imageslist.get 0 bitmap bitm...