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. B. Checkout Assistant 01背包变形

    http://codeforces.com/problemset/problem/19/B 对于每个物品,能偷多ti个,那么先让ti + 1, 表示选了这个东西后,其实就是选了ti + 1个了.那么只 ...

  2. jdk8 Lambda表达式与匿名内部类比较

    Labmda表达式与匿名内部类 前言 Java Labmda表达式的一个重要用法是简化某些匿名内部类(Anonymous Classes)的写法.实际上Lambda表达式并不仅仅是匿名内部类的语法糖, ...

  3. TreeMap的使用

    Map<Integer, String> map = new TreeMap<Integer, String>();//TreeMap本身具有排序功能(默认按键升序排序) ma ...

  4. bzoj 1051 (强连通) 受欢迎的牛

    题目:这里 题意: Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为 ...

  5. XHTML标签的嵌套规则分析

    在 XHTML 的语言里,我们都知道:ul 标签包含着 li.dl 标签包含着 dt 和 dd——这些固定标签的嵌套规则十分明确.但是,还有许多标签是独立的,它们没有被捆绑在一起,比如 h1.div. ...

  6. jetty服务器启动方法总结【备用】

    1. 使用Java命令启动 java -jar start.jar ctrl + c 关闭 终端窗口一直存在 2. 使用Java命令启动2 java -jar start.jar & 启动成功 ...

  7. pil

    http://effbot.org/imagingbook/ 一.安装 pip install PIL --allow-external PIL --allow-unverified PIL   出现 ...

  8. HTML5中canvas大小调整

    今天用到canvas元素,发现它的大小不是像普通dom元素一样,直接设置css样式可以改变的,它会由自己原本的大小伸缩. 例如, <canvas id='canvas'></canv ...

  9. 一个CURL

    CURL curl是利用url语法规则来传输文件,数据的工具,主要实现和服务器中网页,资源传输的工具.这里有一个关于感冒还没好的段子. 1.去phpini开启curl扩展,重启阿帕奇或者配置环境变量或 ...

  10. 一条SMS最大字符数,字符数达到多少按MMS处理

    1,一条SMS最大字符数 ----------------------------------------- android\frameworks\opt\telephony中 com.android ...