1、问题概述

  NFA 和 DFA浅析---要深入了解正则表达式,必须首先理解有穷自动机。

有穷自动机(Finite Automate)是用来模拟实物系统的数学模型,它包括如下五个部分:

    • 有穷状态集States
    • 输入字符集Input symbols
    • 转移函数Transitions
    • 起始状态Start state
    • 接受状态Accepting state(s)(终止状态)

  下图为一台有穷自动机

  

  可以看到,该自动机包含四个状态(有限状态)q0, q1, q2, q3,两个输入字符a, b,转移函数如图所示,起始状态为q0,接受状态为q3。

  有穷自动机,按照转移函数的不同,又可分为确定型有穷自动机(Determinism Finite Automate, DFA),与非确定型有穷自动机(Non-determinism Finite Automate, NFA)
  非确定有穷自动机容许转移函数不确定,换句话说,对任意状态,输入任意一个字符,可以转移到0个,1个或者多个状态。

  下图是一台非确定有穷自动机,可以看到,对状态q0输入字符a,既可以转移到q0,也可以转移到q1,这就是“非确定”的意义所在。

  对某个自动机来说,如果从起始状态,接受一系列输入字符,可以转移到接受状态,即认为这一系列字符可以被自动机接受。
  如果两台自动机能够接受的输入字符串(或者叫做“正则语言”Regular Language)完全相同,则这两台自动机是等价的。可以证明,对于每一个非确定有穷自动机,都存在与之等价的确定型有穷自动机(证明略)。

  正则表达式就是建立在自动机的理论基础上的:用户写完正则表达式之后,正则引擎会按照这个表达式构建相应的自动机(可能是NFA,也可能是DFA,但它们必定是等价的),若输入一串文本之后,自动机抵达了接受状态,则这串文本可以“匹配”用户指定的正则表达式。

  下面是同一个正则表达式 a|ab 对应的NFA和DFA

  

  在Mastering Regular Expression中,Friedl首先分析了NFA和DFA的区别,DFA比较快,但不提供Backtrack(回溯)功能,NFA比较慢,但提供了Backtrack功能

  在分析两种引擎的匹配过程时,Friedl指出,NFA是基于表达式的(Regex-Directed),而DFA是基于文本的(Text-Directed)。

  举例来说,对于正则表达式
to(nite|knight|night),NFA在匹配最开始两个字符(to)之后,剩下的三个组件(component)是 nite,
knight 和
night,于是正则引擎会依次尝试这三个选择分支(每次尝试一个);而DFA在匹配最开始两个字符之后,会将剩下的三个选择拆分作字符,并行尝试,也就是说,匹配
to 之后,先匹配 k 或者 n ,如果 k 不能匹配,则放弃 knigth 所在的分支,再匹配 i ,再匹配 t 或 g
……这样继续下去,直到匹配结束。

  不幸的是,Friedl对匹配过程的分析,是完全错误的——引擎的不同,是指构建的自动机的不同,而不是匹配算法的不同!

  DFA引擎在任意时刻必定处于某个确定的状态,而NFA引擎可能处于一组状态之中的任何一个,所以,NFA引擎必须记录所有的可能路径(trace
multiple possible routes through the
NFA),NFA之所以能够提供Backtrack的功能,原因就在这里。

  传统的NFA匹配算法是带回溯的深度优先搜索(backtracking depth-first search,就是上文所说的Regex-Based过程),而新的PCRE算法提供了效率更高的广度优先搜索,可以同时保持所有可能的NFA状态(请参考http://www.cl.cam.ac.uk/Teaching/current/RLFA/,尤其是Lecture Notes的section 2.2)。

  Friedl的错误就在这里,他混淆了应用PCRE算法的NFA与DFA的匹配过程。需
要指出的是,即使应用PCRE算法,NFA的速度仍然低于DFA,这是由NFA需要同时保存多种可能的性质决定的。从理论上说,如果我们不需要应用
Backtrack,完全可以从NFA构造出等价的DFA,再进行匹配,这样能大大提高速度——代价是,DFA需要更多的空间。

原文地址:http://www.cnblogs.com/u2usoft/archive/2006/06/06/419003.html

endl;

参考网址:

  http://blog.csdn.net/yukuninfoaxiom/article/details/6057736

编译系统中的 NFA/DFA算法理解的更多相关文章

  1. NFA/DFA算法

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

  2. 编译系统中的LR与LL理解

    编译原理:LL(1),LR(0),SLR(1),LALR(1),LR(1)对比 LL(1)定义:一个文法G是LL(1)的,当且仅当对于G的每一个非终结符A的任何两个不同产生式 A→α|β,下面的条件成 ...

  3. 敏感词汇过滤DFA算法

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...

  4. Java 利用DFA算法 屏蔽敏感词

    原文:http://www.open-open.com/code/view/1435214601278 import java.io.BufferedReader; import java.io.Fi ...

  5. java实现敏感词过滤(DFA算法)

    小Alan在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解. 敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxo ...

  6. 利用 DFA 算法实现文字过滤

    一.DEA 算法简介 在实现文字过滤的算法中,DFA是唯一比较好的实现算法. DFA 全称为:Deterministic Finite Automaton,即确定有穷自动机.其特征为:有一个有限状态集 ...

  7. 基于DFA算法、RegExp对象和vee-validate实现前端敏感词过滤

    面临敏感词过滤的问题,最简单的方案就是对要检测的文本,遍历所有敏感词,逐个检测输入的文本是否包含指定的敏感词. 很明显上面这种实现方法的检测时间会随着敏感词库数量的增加而线性增加.系统会因此面临性能和 ...

  8. DFA算法实现敏感词过滤

    DFA算法:即确定有穷自动机,简单点说就是,它是是通过event和当前的state得到下一个state,即event+state=nextstate.理解为系统中有多个节点,通过传递进入的event, ...

  9. 关于KMP算法理解(快速字符串匹配)

    参考:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 2016-08- ...

随机推荐

  1. HDU 1251统计难题

    统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submi ...

  2. OAuth 2.0 Threat Model and Security Considerations (rfc6819)

    Authorization server The following data elements are stored or accessible on the authorization serve ...

  3. Finereport集群配置

    增加配置文件cluster.xml 将配置包resource文件夹下的cluster.xml打开,如果没有cluster.xml,则新建一个,基本内容如下: <?xml version=&quo ...

  4. centos从日志文件查找关键字的日志并生成文件

    grep "unset user wechat user_id:" app* | tee wechat_log

  5. DataRead 和DataSet区别

    dataset表示一个数据集,是数据在内存中的缓存. 可以包括多个表DatSet 连接数据库时是非面向连接的.把表全部读到Sql中的缓冲池,并断开于数据库的连接 datareader 连接数据库时是面 ...

  6. sql 将8位字符串转换成日期型

    将8位字符串转换成日期型,方法如下: ),)

  7. 关于C# DataTable 的一些操作

    经常操作DATATABLE  对于一些不需要再通过sql 来重复操作的   可以通过操作datatable来达到同样的效果 方法一: 也是广为人知的一种: YourDataTable.Columns. ...

  8. checkbox全选-取消-再全选没有显示问题

    源码: <input type="checkbox" id="cleckAll" />全选 <div class="list&quo ...

  9. 为何PHP插入mysql的中文是乱码?【坑】

    依然没有找到最终的解决方法,PHP插入的中文在phpmyadmin中看是乱码,但是用PHP获取之后显示正常: 可以在phpmyadmin中直接插入中文,在PHPmyadmin中显示正常,用PHP获取中 ...

  10. 一些PHP性能的优化

      PHP优化对于PHP的优化主要是对php.ini中的相关主要参数进行合理调整和设置,以下我们就来看看php.ini中的一些对性能影响较大的参数应该如何设置. # vi /etc/php.ini ( ...