什么是狀態(tài)機?
關(guān)于狀態(tài)機的一個極度確切的描述是它是一個有向圖形,由一組節(jié)點和一組相應(yīng)的轉(zhuǎn)移函數(shù)組成。狀態(tài)機通過響應(yīng)一系列事件而“運行”。每個事件都在屬于“當(dāng)前”節(jié)點的轉(zhuǎn)移函數(shù)的控制范圍內(nèi),其中函數(shù)的范圍是節(jié)點的一個子集。函數(shù)返回“下一個”(也許是同一個)節(jié)點。這些節(jié)點中至少有一個必須是終態(tài)。當(dāng)?shù)竭_終態(tài),狀態(tài)機停止。
但一個抽象的數(shù)學(xué)描述(就像我剛給出的)并不能真正說明在什么情況下使用狀態(tài)機可以解決實際編程問題。另一種策略就是將狀態(tài)機定義成一種強制性編程語言,其中節(jié)點也是源碼行。從實用角度看,這個定義盡管精確,但它和第一種描述一樣,都是紙上談兵、毫不實用。(對于說明型、函數(shù)型或基于約束的語言,例如,Haskell、Scheme 或 Prolog,不一定會發(fā)生這種情況。)
讓我們嘗試使用更適合身邊實際任務(wù)的例子來進行討論。邏輯上,每個規(guī)則表達式都等價于一個狀態(tài)機,而每個規(guī)則表達式的語法分析器都實現(xiàn)這個狀態(tài)機。實際上,大多數(shù)程序員編寫狀態(tài)機時,并沒有真正考慮到這一點。
在以下這個例子中,我們將研究狀態(tài)機的真正探索性定義。通常,我們有一些不同的方法來響應(yīng)一組有限數(shù)量的事件。某些情況下,響應(yīng)只取決于事件本身。但在其它情況下,適當(dāng)?shù)牟僮魅Q于以前的事件。
本文中討論的狀態(tài)機是高級機器,其目的是演示一類問題的編程解決方案。如果有必要按響應(yīng)事件行為的類別來討論編程問題,那么您的解決方案很可能是顯式狀態(tài)機。
文本處理狀態(tài)機
最可能調(diào)用顯式狀態(tài)機的一個編程問題涉及到處理文本文件。處理文本文件通常包括讀取信息單元(通常叫做字符或行),然后對剛讀取的單元執(zhí)行適當(dāng)操作。 某些情況下,這個處理是“無狀態(tài)的”(即每個這樣的單元都包含了足夠的信息,可以正確確定要執(zhí)行什么操作)。在其它情況下,即使文本文件不是完全無狀態(tài), 數(shù)據(jù)也只有有限的上下文(例如,操作取決于不比行號更多的信息)。但是,在其它常見文本處理問題中,輸入文件是極具“狀態(tài)”的。 每一塊數(shù)據(jù)的含義取決于它前面的字符串(也許是它后面的字符串)。報告、大型機數(shù)據(jù)輸入、可讀文本、編程源文件和其它種類的文本文件都是有狀態(tài)的。 一個簡單例子是可能出現(xiàn)在 Python 源文件中的一行代碼:
myObject = SomeClass(this, that, other)
這行表示,如果恰好有以下幾行圍繞著這一行,則有部分內(nèi)容不同:
"""How to use SomeClass:myObject = SomeClass(this, that, other)"""
我們應(yīng)知道我們處于“塊引用” 狀態(tài) 以確定這行代碼是一部分注釋而不是 Python 操作。
新聞熱點
疑難解答
圖片精選