有限狀態機

2021-10-12 12:26:47 字數 2708 閱讀 2074

在程式設計的時候,經常需要根據乙個當前狀態和各種可能的輸入來實現不同的邏輯以及維護狀態的變化,一般用if…else或者swith…case來實現,這其實就是狀態機的思想。掌握一些關於狀態機的理論知識和工具,能夠更好更快地寫出狀態機的**,尤其是當狀態和輸入較多的時候。本文從簡單的例子開始,介紹狀態機的一些知識,然後再介紹各種不同的c++實現。

先來看乙個非常簡單的面試題怎麼用狀態機來實現:

有乙個ascii字串,其中包含數字和非數字,請找出其中所有的連續的數字.比如說對於字串:

abc123fgx#@ad5lkyo0936sda*xc342s&

找到所有連續的數字如下:

1235

0936

342

程式設計逐個遍歷題目所需要處理的字串,每次處理乙個字元,字元分為兩種:數字(number)和非數字(other),當前狀態也可以分為兩種:「處在記錄數字的狀態中(number)」和「連續的其它非數字狀態(other)」。在寫**之前,可以用「狀態轉移表」來分析每種狀態對應每個字元的處理邏輯。**如下所示,用行和列分別表示所有的狀態和對應的輸入型別,有n種狀態和m種輸入的狀態機就繪製成乙個nxm的**,然後在每一格中填寫對應的處理的邏輯。

每一格的處理邏輯用「新狀態/動作行為」的格式來填寫,「新狀態」表示當前狀態遇到當前輸入時,當前狀態應該被更改為的目標狀態,「動作行為」表示在狀態改變的同時需要做的一些程式邏輯,例如上面**中的「記錄數字開始位置」和「拷貝儲存數字串」。

「狀態轉移表」的好處是要求將每個格仔都填滿,不會遺漏。將**全部填滿以後,只要把**的內容翻譯成程式**即可。對應的c++**如下:

#include #include #include #include // std::isdigit

using namespace std;

// 找出連續的數字,通過乙個vector返回,題目並不要求轉換成int型別,直接用string即可。

vectorfindnumbers(const string& str) state = other;

size_t num_begin; // 當前解析到的連續數字的起始位置

// 逐個遍歷每個字元

for(size_t i = 0; i < str.length(); ++i)

// 字串以數字結尾時,需要加上這行判斷,後面再解釋。

if(i == str.length() - 1)

} else }}

return ret;

}int main()

;using ll =

long

long

; state state = start;

int sign =1;

unordered_map> table =},

},},

}};int

get_col

(char c)

public

: ll res =0;

void

input

(char c)

else

if(state == in_number)}}

;class

solution

return dfa.res;}}

;

例題3:

考慮終止狀態的狀態機

狀態轉移圖

有限狀態機

有限狀態機 finite state machine,fsm 又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。狀態儲存關於過去的資訊,就是說 它反映從系統開始到現在時刻的輸入變化。轉移指示狀態變更,並且用必須滿足來確使轉移發生的條件來描述它。動作是在給...

有限狀態機

以前,只碰到過 陣列中所有數字只出現2次,只有乙個出現1次,找這個數的問題 每次迴圈異或陣列中元素,最後的結果就是single one。這次換作出現3次就懵逼了,主要原因,沒有使用過有限狀態機,應該說是連概念都沒有,所以這次一定要好好記錄一下 關於這道題的解釋discussion中woshidais...

有限狀態機

需要掌握的名詞 數字系統有兩大類有限狀態機 finite state machine,fsm moore狀態機和mealy狀態機。狀態機名 次態輸出 moore摩爾 f 現狀,輸入 g 現狀 mealy公尺粒 f 現狀,輸入 g 現狀,輸入 mealy型狀態機 下一狀態不但與當前狀態有關,還與當前輸...