有限状态机FSM详解及其实现

本文介绍有限状态机(FSM)的基本概念及其工作原理,包括状态转换图的构成要素,如起始状态、结束状态及消亡状态等,并详细讲解了两种FSM实现方法:基于可执行代码和映射表的方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有限状态机,也称为 FSM(Finite State Machine) ,其在任意时刻都处于有限状态集合中的某一状态。当其获得一个 输入字符 时,将从 当前状态 转换到 另一个状态 ,或者仍然 保持在当前状态 。任何一个FSM都可以用状态转换图来描述,图中的节点表示FSM中的一个状态,有向加权边表示输入字符时状态的变化。如果图中不存在与当前状态与输入字符对应的有向边,则FSM将进入 “消亡状态 (Doom State) ”,此后FSM将一直保持“消亡状态”。状态转换图中还有两个特殊状态:状态1称为 “起始状态” ,表示FSM的初始状态。状态6称为 “结束状态” ,表示成功识别了所输入的字符序列。

在启动一个FSM时,首先必须将FSM置于“起始状态”,然后输入一系列字符,最终,FSM会到达“结束状态”或者“消亡状态”。

说明:

在通常的FSM模型中,一般还存在一个“接受状态”,并且FSM可以从“接受状态”转换到另一个状态,只有在识别最后一个字符后,才会根据最终状态来决定是否接受所输入的字符串。此外,也可以将“其实状态”也作为接受状态,因此空的输入序列也是可以接受的。

FSM的实现

程序设计思路大致如下:

  • 使用状态转换图描述FSM
  • 状态转换图中的结点对应不同的状态对象
  • 每个状态对象通过一个输入字符转换到另一个状态上,或者保持原状态不变。

通过输入字符从一个状态切换到另一个状态的过程,我们称之为一个 映射 。在计算机程序设计中, 我们可以有两种表示映射的方法:

  • 通过算法表示,即“可执行代码(Executable Code)”方式
  • 通过一张映射表,即“被动数据(Passive Data)”方式
如下详细介绍这两种实现方式:
  • 通过Executable Code 实现映射的FSM 

这种方式主要是通过条件分支来处理不同的字符,如if或者switch语句块,如

1 State* State1::Transition(char c)
 2 {
 3     switch(c)
 4     {
 5     case 'A':
 6         return &s2;
 7     case 'B':
 8         return &s3;
 9     case 'C':
10         return &s4;
11     case 'D':
12         return &s5;
13     case '\0':
14         return NULL;
15     default:
16         return NULL;
17     }
18 }
1 // fsm_with_executable_code.h
  2 #ifndef FSM_WITH_EXECUTABLE_CODE_H
  3 #define FSM_WITH_EXECUTABLE_CODE_H
  4 
  5 #include <string.h>
  6 
  7 class State
  8 {
  9 public:
 10     virtual State* Transition(char c) = 0;
 11 };
 12 
 13 class Fsm
 14 {
 15 public:
 16     Fsm();
 17     void Reset();            // move to start state
 18     void Advance(char c);    // advance one transition
 19     int EndState();
 20     int DoomState();
 21 
 22 private:
 23     State* p_current;   // &s1, &s2, ..., &s6; NULL ==> doom
 24 };
 25 
 26 
 27 class State1 : public State
 28 {
 29 public:
 30     State* Transition(char c);
 31 };
 32 
 33 class State2 : public State
 34 {
 35 public:
 36     State* Transition(char c);
 37 };
 38 
 39 class State3 : public State
 40 {
 41 public:
 42     State* Transition(char c);
 43 };
 44 
 45 class State4 : public State
 46 {
 47 public:
 48     State* Transition(char c);
 49 };
 50 
 51 class State5 : public State
 52 {
 53 public:
 54     State* Transition(char c);
 55 };
 56 
 57 class State6 : public State
 58 {
 59 public:
 60     State* Transition(char c);
 61 };
 62 
 63 #endif // FSM_WITH_EXECUTABLE_CODE_H
 64 
 65 // fsm_with_executable_code.cc
 66 #include "fsm_with_executable_code.h"
 67 
 68 State1 s1;
 69 State2 s2;
 70 State3 s3;
 71 State4 s4;
 72 State5 s5;
 73 State6 s6;
 74 
 75 Fsm::Fsm()
 76 {
 77     p_current = NULL;
 78 }
 79 
 80 void Fsm::Reset()
 81 {
 82     p_current = &s1;
 83 }
 84 
 85 void Fsm::Advance(char c)
 86 {
 87     if (p_current != NULL)
 88         p_current = p_current->Transition(c);
 89 }
 90 
 91 int Fsm::EndState()
 92 {
 93     return p_current == &s6;
 94 }
 95 
 96 int Fsm::DoomState()
 97 {
 98     return p_current == NULL;
 99 }
100 State* State1::Transition(char c)
101 {
102     switch(c)
103     {
104     case 'A':
105         return &s2;
106     case 'B':
107         return &s3;
108     case 'C':
109         return &s4;
110     case 'D':
111         return &s5;
112     case '\0':
113         return NULL;
114     default:
115         return NULL;
116     }
117 }
118 
119 State* State2::Transition(char c)
120 {
121     switch(c)
122     {
123     case 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值