狀態機在計算機中的應用

2021-09-20 03:16:55 字數 1823 閱讀 6738

當你參加比賽前,教練會問你狀態如何;當你參加考試前,父母會問你狀態如何;當你參加演出前,夥伴會問你狀態如何。如果狀態不好,那麼你在這些活動的表現就可能不盡如人意,相反則可能有出人意料的表現。

可見,乙個人狀態的好壞會直接影響他的真實表現。但是,今天的狀態不佳,明天的狀態卻有可能很好,可見狀態也是會變化的。人如此,計算機也一樣——計算機的很多思想都來自於人的生活,因此生活中的狀態在計算機中也是遍地開花。

我最早接觸狀態機的概念是在學習編譯原理的課程中。當時覺得狀態機雖然在詞法分析中發揮了神奇的作用,但總覺得抽象不太容易理解。後來在計算機的學習和工作中慢慢了解到狀態機在計算機中還有很多應用,例如正規表示式。

正規表示式使用單個字串(如圖一)來描述、匹配一系列符合某個句法規則的字串。在很多文字編輯器裡,正規表示式通常被用來檢索、替換那些符合某個模式的文字。比如[abc]d既可以匹配ad,也可以匹配bdcd^1[3|4|5|7|8][0-9]\d$則可以匹配目前的手機號碼。

圖一:正規表示式

那麼,正規表示式是如何起作用的呢?這就需要了解正規表示式的引擎了。目前主流的引擎分為 3 類:dfa(確定的有限狀態機),傳統型 nfa **(非確定的有限狀態機),posix nfa**。

那什麼是確定的有限狀態機?數學上的嚴謹定義是確定的有限狀態機從起始狀態開始,乙個字元接乙個字元地讀入乙個字串,並根據給定的轉移函式一步一步地轉移至下乙個狀態。通過狀態圖,我們可以清晰的看出這類狀態機的大致模樣(如圖二)。

圖二:有限狀態機

簡單來看,當 s1 狀態在輸入 0 的時候會進入 s2 的狀態,而s2的狀態在輸入 0 的時候則會重新回到 s1 的狀態,這種狀態轉移圖正好符合正則表達的內涵。我們可以將某個正規表示式生成一張對應的狀態圖,然後根據輸入的字串來進行乙個狀態轉移,如果過濾完該字串後剛好到達有向圖的結尾,那麼該輸入字串則匹配了該正規表示式。

就拿之前提到的手機號碼舉例,^1[3|4|5|7|8][0-9]\d$對應的有向圖如(圖三),只有在輸入符合條件的手機號碼時,狀態有向圖才會從最開始狀態走到結束狀態。對於複雜的正則表達,借助狀態有向圖則可以達到事半功倍的效果。

圖三:狀態有向圖

除了在正規表示式上的應用外,狀態機還在網路協議中發揮了重要的作用。我們都知道 cdn 中離不開快取系統,而被我們熟知的ats ( apache traffic server )則是乙個由狀態機模型實現的非同步事件處理程式。狀態機模型具有很強的描述系統行為的能力,尤其是針對具有事件驅動的併發的特徵的問題,用狀態機來建模非常合適。將狀態機作為一種構建系統的基本模組來對系統進行分解,將會使很多原本複雜的問題簡單化。由此可見,狀態機模型的引入可以有效解決協議處理過程的複雜性從而將系統變得簡單和穩定。

曾經有個理論說,你最多通過其中的 6 個人就可以和世界上任何一位陌生人建立聯絡,果真如此的話,每個人的認識狀態圖也未免有些簡單吧,不過每次的狀態轉移可不是這麼輕鬆的哦。

另:本文由upyun cdn工程師 楊陽 供稿

負數在計算機中的表示

今天,老大讓我調查乙個浮點數轉換為整數的問題。自己就查了些資料,順便複習一下原碼 反碼和補碼。原碼 將乙個整數,轉換成二進位制,就是其原碼。如單位元組的5的原碼為 0000 0101 5的原碼為1000 0101。反碼 正數的反碼就是其原碼 負數的反碼是將原碼中,除符號位以外,每一位取反。如單位元組...

負數在計算機中的儲存

問乙個基本的問題。負數在計算機中如何表示?舉例來說,8在計算機中表示為二進位制的1000,那麼 8怎麼表示呢?很容易想到,可以將乙個二進位制位 bit 專門規定為符號位,它等於0時就表示正數,等於1時就表示負數。比如,在8位機中,規定每個位元組的最高位為符號位。那麼,8就是00001000,而 8則...

負數在計算機中的表示

原碼 將乙個整數,轉換成二進位制,就是其原碼。如單位元組的5的原碼為 0000 0101 5的原碼為1000 0101。反碼 正數的反碼就是其原碼 負數的反碼是將原碼中,除符號位以外,每一位取反。如單位元組的5的反碼為 0000 0101 5的原碼為1111 1010。補碼 正數的補碼就是其原碼 負...