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. css总结

    1. css中的role属性 html 里面的 role 本质上是增强语义性,当现有的HTML标签不能充分表达语义性的时候,就可以借助role来说明.通常这种情况出现在一些自定义的组件上,这样可增强组 ...

  2. android xml特殊字符

    @ 对应 @ : 对应 :   对应 空格 对应 空格 ! 对应 ! " 对应 " # 对应 # $ 对应 $ % 对应 % & 对应 & ' 对应 ´ ( 对应 ...

  3. JavaScript数组的一些方法集合

    数组方法集合 push()添加到数组末尾,并返回修改后数组的长度 var a=array.push('a','b'); alert(a);//2 pop() 移除数组最后一项,返回移除的项. shif ...

  4. Fedora22编译Qt3.3.X

    FC22编译QT3 安装g++ dnf install gcc-c++ 1,configure ./configure -thread -no-nis -system-libpng -system-l ...

  5. 問題排查:DataGridView 資料行下拉選單,資料繫結階段顯示 DataGridViewComboBoxCell 值無效

    可能原因: 1.下拉選單的選項資料繫結晚於 DataGridView 的資料繫結 2.下拉選單的 DataPropertyName 屬性,比 DisplayMember.ValueMember 早賦值 ...

  6. 各大门户网站的css初始化代码

    腾讯QQ官网 css样式初始 body,ol,ul,h1,h2,h3,h4,h5,h6,p,th,td,dl,dd,form,fieldset,legend,input,textarea,select ...

  7. 使用Axis2 插件 报错"An error occurred while completing process -java.lang.reflect.InvocationTargetException"

    参考 http://blog.csdn.net/sunitjy/article/details/6793654

  8. 使用afinal下载文件并且在状态栏中显示下载的进度

    2013年10月23日,今天是在“我在找你信息服务有限公司”第一天上班,公司给提出了这样一个要求:下载本公司的app,并且在下载的过程中要在状态栏中显示下载的进度,并且,可以暂停和继续下载. 下面是我 ...

  9. css例子

    6.背景图像渐变的制作body{ background:#ccc url(xxx.gif)rpeat-x或y:} 7.给一个区块加上背景#branding{ width:700px: height:2 ...

  10. LeetCode(124) Binary Tree Maximum Path Sum

    题目 Given a binary tree, find the maximum path sum. For this problem, a path is defined as any sequen ...