适合读者:软考中级备考同学
阅读时间:4分钟
内容:子集构造法原理、算法步骤、示例、例题
1. 为什么需要NFA转DFA?
NFA(非确定有限自动机)构造直观,但直接模拟运行效率较低(需要回溯或并行跟踪多个状态)。DFA(确定有限自动机)每个输入符号唯一确定下一状态,模拟运行速度快,更易于硬件实现或编程。
理论 :NFA和DFA的识别能力等价------任何NFA都可以转换为等价的DFA。转换的标准算法称为子集构造法(Subset Construction)。
软考中常考查子集构造法的基本思想或简单实例的转换。
2. 核心概念:ε-闭包
在NFA中,允许不读入任何输入符号(ε)就转移状态。转换前需要先理解ε-闭包:
- ε-闭包 (ε-closure):从某个状态出发,通过0条或多条ε转移所能到达的所有状态的集合。
- 例如:状态A有ε边到B,B有ε边到C,则 ε-closure({A}) = {A, B, C}。
3. 子集构造法算法步骤
目标:构造一个DFA,使得它接受的字符串集合与原NFA完全相同。
-
初始化
- 计算NFA初始状态的ε-闭包,记为
S0。这个S0就是DFA的初始状态。 - 将
S0加入未处理队列,并作为DFA的一个状态。
- 计算NFA初始状态的ε-闭包,记为
-
对每个未处理的DFA状态(即NFA状态子集),处理所有输入符号
假设当前DFA状态为
T(T 是一个 NFA 状态子集)。对于每个输入符号a(通常来自字母表 Σ):- 计算
move(T, a):从 T 中任一状态出发,读入一个a所能到达的所有NFA状态的集合。 - 计算
ε-closure(move(T, a)),得到一个新的NFA状态子集U。 - 如果
U不为空,且尚未在DFA中出现过,则将U作为一个新的DFA状态加入队列。 - 记录DFA中从
T到U在输入a下的转移。
- 计算
-
标记终止状态
如果DFA的某个状态(即NFA状态子集)中包含NFA的至少一个终止状态,那么该DFA状态为终止状态。
-
重复直到所有状态都处理完毕。
4. 示例:NFA转DFA
4.1 原NFA描述
- 状态:A(初始),B,C(终止)。
- ε转移:无。
- 转移:
- A 读 0 → A 和 B
- A 读 1 → A
- B 读 1 → C
- 其他转移无。
这个NFA识别所有以 01 结尾的串。
4.2 转换过程
第1步:初始状态 ε-closure({A}) = {A}(无ε转移)。记为 D_A = {A}。
第2步:处理 D_A = {A}:
- 输入 0:move({A},0) = {A, B},ε-closure({A,B}) = {A, B} → 新状态 D_{AB} = {A, B}
- 输入 1:move({A},1) = {A},ε-closure({A}) = {A} → 已存在 D_A
第3步:处理 D_{AB} = {A, B}:
- 输入 0:move({A,B},0) = {A, B}(A→A,B;B无0),闭包 {A,B} → 已有 D_{AB}
- 输入 1:move({A,B},1) = {A, C}(A→A;B→C),闭包 {A, C} → 新状态 D_{AC} = {A, C}
第4步:处理 D_{AC} = {A, C}:
- 输入 0:move({A,C},0) = {A, B}(A→A,B;C无0),闭包 {A,B} → 已有 D_{AB}
- 输入 1:move({A,C},1) = {A}(A→A;C无1),闭包 {A} → 已有 D_A
第5步:标记终止状态。原NFA的终止状态是C。在DFA状态中,D_{AC} 包含C,因此 D_{AC} 是终止状态。
4.3 得到的DFA
- 状态:D_A(初始),D_{AB},D_{AC}(终止)
- 转移:
- D_A 读0 → D_{AB};读1 → D_A
- D_{AB} 读0 → D_{AB};读1 → D_{AC}
- D_{AC} 读0 → D_{AB};读1 → D_A
可重新命名:将 D_A 命为 q0,D_{AB} 命为 q1,D_{AC} 命为 q2。
5. 简化技巧与注意事项
- ε闭包 是子集构造法的关键,务必先计算所有状态的ε闭包。
- 如果NFA没有ε转移,那么每个状态子集的ε闭包就是它本身,过程会简单很多。
- DFA的状态数在最坏情况下可能是指数级(相对于NFA状态数),但实际题目中通常很小。
- 考试中常考的是简单NFA(2~4个状态)的转换,只需按步骤逐步推导即可。
6. 经典例题
题目1:已知NFA的转移表如下(无ε转移):
| 状态 | 输入a | 输入b |
|---|---|---|
| 0 | {0,1} | {0} |
| 1 | {2} | {2} |
| 2 | {} | {} |
初始状态0,终止状态2。用子集构造法转换为DFA。
解:
- 初始闭包 {0} → D0
- D0 读a:move({0},a)={0,1} → D01
- D0 读b:move({0},b)={0} → D0
- D01 = {0,1} 读a:{0,1}→{0,1,2}(0→0,1;1→2)→ D012
- D01 读b:{0,1}→{0,2} → D02
- D012 = {0,1,2} 读a:{0,1,2}→{0,1,2} → D012
- D012 读b:{0,1,2}→{0,2} → D02
- D02 = {0,2} 读a:{0,2}→{0,1} → D01
- D02 读b:{0,2}→{0} → D0
- 终止状态:包含原终止状态2的DFA状态:D012, D02。
答案:DFA有4个状态:D0(初始),D01,D012(终止),D02(终止)。
题目2 (概念):子集构造法的作用是( )。
A. 将DFA转化为NFA
B. 将NFA转化为等价的DFA
C. 最小化DFA
D. 消除ε转移
答案:B
7. 记忆口诀
NFA转DFA,子集构造法。
初态闭包起,每个符号算。
移动取闭包,新集加进来。
含终态即终态,确定化完成。
8. 给备考同学的一句话
子集构造法是软考中有限自动机部分的进阶考点。理解ε-闭包 和move两个操作,按步骤逐步推导,就能完成转换。考试中一般不会要求处理过于复杂的NFA,掌握教材上的简单例子即可。如果遇到选择题,记住"子集构造法"这个名字及其作用(NFA→DFA)就能得分。
🔔 本专栏日更2篇,点击头像 → 专栏《软考中级高频考点》订阅
#软考中级 #软件设计师 #NFA转DFA #子集构造法 #有限自动机