一、从NFA到DFA的转换

例如下图:

DFA的每个状态都是一个由NFA中的状态构成的集合,即NFA状态集合的一个子集

r =aa*bb*cc*

二、从带有ε-边的NFA到DFA的转换

r=0*1*2*

三、子集构造法( subset construction)

 输入:NFA N
 输出:接收同样语言的DFA D
 方法:一开始,ε-closure ( s0 )是Dstates 中的唯一状态,且它未加标记;

while(在Dstates中有一个未标记状态T )
{
给T加上标记;
for(每个输入符号a)
{
U = ε-closure(move(T, a));
if ( U不在Dstates中)
将U加入到Dstates中,且不加标记;
Dtran[T, a]=U ;
}
}

四、计算 ε-closure (T )

将T的所有状态压入stack中;将ε-closure  (T )初始化为 T ;

 while(stack非空)
{
  将栈顶元素 t 给弹出栈中;
  for(每个满足如下条件的u :从t出发有一个标号为ε的转换到达状态u)
    if ( u不在ε-closure (T )中)
    {
      将u加入到ε-closure (T )中;将u压入栈中;
    }
}

接下来我们结合一个例题来具体实践一下根据正规文法构造NFA,接着确定化NFA,最后化简DFA

例:例题:为正规文法G[S]

S→aA|bQ

A→aA|bB|b

B→bD|aQ

Q→aQ|bD|b

D→bB|aA

E→aB|bF

F→bD|aE|b

构造相应的DFA。

答:

首先消除无用符号及其所在的产生式:
观察题目我们可以发现,E不出现在任何产生式的右部,所以E是无效符号,
删除E所在的产生式之后,符号F也不出现在任何产生式的右部,则F是无效符号,
删除F及其所在产生式。此时除了文法开始符号S之外,其余非终结符都是从S可达的。

 

接着便只需要为正规文法G[S]
       S→aA|bQ
       A→aA|bB|b
       B→bD|aQ
       Q→aQ|bD|b
       D→bB|aA
  构造相应的最简DFA。 

 
接着我们根据珍贵文法构造出下图的NFA:
 

接下来我们将NFA进行确定化,新增一个状态T表示终止态:

构建下图的子集表,最开始只有起始态:

根据上图NFA,可得下图:

出现了两个新增状态子集{ A }{ Q},我们把它加入到状态集中:

根据NFA可得出下表:

出现了两个新增状态子集{ B,T}{ D,T}(红色背景),而{ A }{ Q}(绿色背景)已经存在与状态集中,可以不做处理。(字体颜色为绿色的T表示终态),

接着我们把新增的状态子集{ B,T}{ D,T}添加到状态集之中:

有NFA可得下表,可以根据上述方法看出,出现了新增状态子集{ B}{ D}(红色背景),而{ A }{ Q}(绿色背景)已经存在与状态集中,可以不做处理。

接着我们把新增的状态子集{ B}{ D}添加到状态集之中

有NFA得出下表,发现已经没有新增的状态子集了:

zhe这时候便可以重命名状态集,其中包含终态(绿色状态T)的子集相应的变成终态:

根据这个状态集表,我们构造DFA:

此时已经完成了NFA转化为DFA的过程,最后我们将DFA进行化简,这里采用的方法是“划分法”

首先我们将这留个状态划分为非终态集 { 0,1,2,5,6 }; 终态集 { 3,4 };

同样的我们首先将DFA的表简单直观的构造出来:

根据上表,可以得出如下图,

当非终态子集{ 0,1,2,5,6 }遇到a时,所得子集为{1,2},包含于{ 0,1,2,5,6 },暂时可以不用再分,转去考虑遇到b时的情况:

我们可以看到,经由b所得到的子集,不包含于任何一个已存在的子集,所以此时需要对非终态集 { 0,1,2,5,6 }进行划分,我们可以观察如下图:

其中0,5,6三个状态经由b所得的子集是包含于已存在的子集{ 0,1,2,5,6 }中的,而状态1,2经由b所得的子集也是包含于已存在的子集{ 3 , 4}中的,所以我们再次划分为{0,5,6},{1,2}, { 3,4 }

这时候首先我们讨论子集{0,5,6}根据DFA表我们可以做出下表,经由a时的结果{1,2}包含于已存在子集:

子集{0,5,6}根据DFA表,经由b时的结果{2,5,6}不包含于任何一个已存在子集:

观察下图:

我们发现需要将状态5,6再次分为一个子集,0单独分一个子集。得到新的已存在状态集:

首先讨论子集{3,4},遇到a,b的情况,如下图;

所以此时子集{3,4}不需要再分。

再讨论子集{1,2},遇到a,b的情况,如下图;

所以此时子集{1,2}也不需要再分。

再讨论子集{5,6},遇到a,b的情况,如下图;

所以此时子集{5,6}也不需要再分.

此时令状态3代表{3,4}(同时也是终态集),把原来到达状态4的弧都导入3,并删除状态4;

状态1代表{1,2},把原来到达状态2的弧都导入1,并删除状态2;

状态5代表{5,6},把原来到达状态6的弧都导入5,并删除状态6;

便得到了化简后的DFA:

结束

如何将 不确定的有穷自动机(NFA) 转化为 确定的有穷自动机(DFA) 并将DFA最简化的更多相关文章

  1. [编译原理代码][NFA转DFA并最小化DFA并使用DFA进行词法分析]

    #include <iostream> #include <vector> #include <cstring> #include "stack" ...

  2. 有穷自动机(NFA、DFA)&正规文法&正规式之间的相互转化构造方法

    在编译原理(第三版清华大学出版社出版)中第三章的词法分析中,3.4.3.5.3.6小节中分别讲解了 1.什么是NFA(不确定的有穷自动机)和DFA(确定的有穷自动机) 2.如何将  不确定的有穷自动机 ...

  3. C# 词法分析器(三)正则表达式

    系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 正则表达式是一种描述词素的重要表示方法.虽然正则表达 ...

  4. 什么是NFA(不确定的有穷自动机)和DFA(确定的有穷自动机)

    本节知识点是<编译原理>第三章-词法分析,学习参考教材为清华大学出版社<编译原理>第三版: 前情提要: 字母表∑1和∑2的乘积( product): ∑1∑2 ={ab|a ∈ ...

  5. NFA转化为DFA

    NFA(不确定的有穷自动机)转化为DFA(确定的有穷自动机) NFA转换DFA,通常是将带空串的NFA(即:ε-NFA)先转化为不带空串的NFA(即:NFA),然后再转化为DFA. 提示:ε是空串的意 ...

  6. NFA引擎匹配原理

    1       为什么要了解引擎匹配原理 一个个音符杂乱无章的组合在一起,弹奏出的或许就是噪音,同样的音符经过作曲家的手,就可以谱出非常动听的乐曲,一个演奏者同样可以照着乐谱奏出动听的乐曲,但他/她或 ...

  7. 正则表达式: NFA引擎匹配原理

    NFA引擎匹配原理 1       为什么要了解引擎匹配原理 一个个音符杂乱无章的组合在一起,弹奏出的或许就是噪音,同样的音符经过作曲家的手,就可以谱出非常动听的乐曲,一个演奏者同样可以照着乐谱奏出动 ...

  8. 子集构造法实现NFA的确定化

    功能: 采用子集构造算法实现NFA的确定化 输入:读取NFA的文件(文件名test.txt),  文件格式: 第一列表示状态名,第二列和第三列分别表示输入字符a和b到达的状态 输出:确定化后的DFA( ...

  9. NFA/DFA算法

    1.问题概述 随着计算机语言的结构越来越复杂,为了开发优秀的编译器,人们已经渐渐感到将词 法分析独立出来做研究的重要性.不过词法分析器的作用却不限于此.回想一下我们的老师刚刚开始向我们讲述程序设计的时 ...

随机推荐

  1. WORD 图片能粘到百度编辑器吗

    在之前在工作中遇到在富文本编辑器中粘贴图片不能展示的问题,于是各种网上扒拉,终于找到解决方案,在这里感谢一下知乎中众大神以及TheViper. 通过知乎提供的思路找到粘贴的原理,通过TheViper找 ...

  2. [luogu]P1463 [SDOI2005]反素数ant[dfs][数学][数论]

    [luogu]P1463 [SDOI2005]反素数ant ——!x^n+y^n=z^n 题目描述 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4. 如果某个正整数x满足: ...

  3. 【HDOJ6621】K-th Closest Distance(主席树,二分)

    题意:给定一个长为n的序列,有m次强制在线的询问,每次询问位置[L,R]中abs(a[i]-p)第k小的值 n,m<=1e5,a[i]<=1e6,p<=1e6,k<=169 思 ...

  4. [CSP-S模拟测试]:Equation(数学+树状数组)

    题目描述 有一棵$n$个点的以$1$为根的树,以及$n$个整数变量$x_i$.树上$i$的父亲是$f_i$,每条边$(i,f_i)$有一个权值$w_i$,表示一个方程$x_i+x_{f_i}=w_i$ ...

  5. python测试redis是否可以使用

    前提打开redis服务,windows打开方式到redis的安装目录命令行输入redis-server from redis import StrictRedis redis = StrictRedi ...

  6. 新建 SecondPresenter 实现类

    package com.test.mvp.mvpdemo.mvp.v6.presenter; import com.test.mvp.mvpdemo.mvp.v6.SecondContract;imp ...

  7. php面试专题---8、会话控制考点

    php面试专题---8.会话控制考点 一.总结 一句话总结: 主要是cookie和session的区别,以及用户禁用cookie之后怎么使用session 1.为什么要使用会话控制技术? 因为http ...

  8. How to pass values across the pages in ASP.net without using Session

    https://stackoverflow.com/questions/14956027/how-to-pass-values-across-the-pages-in-asp-net-without- ...

  9. EZOJ #362历史

    分析 就是保存前pi-1个数每个ai出现多少次 然后维护这些数当前剩余的最大值 每次和新加进来的比较即可 如果新的大直接取 否则新的最大值一定不大于原来的最大值 因此o(n) 代码 #include& ...

  10. delphi 神经网络 学习

    https://github.com/uldercarrilho/ParallelNeuralNetwork