自己实现一个 DFA 串模式识别器(二)
正规表达式的实现原理
上文讨论了串的模式的表达,即正规表达式。那么这一小节将讨论我们实现一个正规表达式的方法和原理。因为我们知道,一个正规表达式对应着一个串模式,而一个串模式又对应着一些列符合该模式描述的规则的串。那么,我们是否可以通过实现出正规表达式,从而实现对一个给定串的判别呢?答案是肯定的。
状态转换图
首先介绍,状态转换图。
状态转换图是一个有向图,由节点和边组成。每个节点代表一个状态,状态之间用箭头连接,称为边。边上的字符表示从该边的出发节点读取一个该边上的字符后,可以抵达改变指向的状态节点。如下图:

状态转换图中具有一个状态标记为 start 状态,被称为初始状态。识别一个字符串时,我们就从这个状态开始。下图展示了能够识别 大于号 或者 大于等于号 的状态转换图:

其开始状态是状态 0,在状态 0 读入下一个字符,如果该字符是 > ,那么则转向状态 1,否则失败。在状态 1 时,读入下一个字符,如果是 + ,则转向状态 2,否则标有 other 的边表明转向状态 3.在状态 2 上有双圈,表示它是接受状态。当进入这个状态时,状态转换图识别了记号 >= 。
通常会有多个状态转换图,每个状态转换图对应者一个类别(如记号)。如果沿着一个状态转换图书别串时失败,那么就需要将前向指针回退到该状态图开始状态时该指针所指向的输入串的位置。并启动下一个状态转换图,试图匹配下一个模式。显然,我们可以通过不断的组合状态转换图来实现更加复杂的串模式匹配。可以说,状态转换图为串模式识别提供了一种有效方法。
所以状态转换图实现了正规表达式和图结构的转换。上面的状态转换图对应着正规表达式:>(\(\epsilon\)|=) 。而图结构十分容易使用计算机实现。
有穷自动机
有穷自动机是更一般化的状态转换图。它可以是确定的即 DFA,也可以是不确定的即 NFA。其中“不确定”的含义是:对于某个输入符号,在同一个状态上存在不止一种转换。我们可以通过构造有穷自动机把正规表达式编译成识别器。二者都可以识别且仅能识别正规集,即能够识别正规表达式所表示的字符串集合。但是二者有着时空上的权衡,DFA 导出的识别器比NFA导出的识别器要快得多,但DFA可能比与之等价的NFA大得多。(注:NFA,DFA 的数学模型定义这里从略)
NFA
由于从正规式转换成不确定的有穷自动机(NFA)更方便,所以先讨论 NFA。
下图是一个 NFA:

它所对应的正规表达式为:(a|b)*abb 。注意,NFA 是用带标记的有向图表示,称为转换图,节点是状态,有标记的边是转换关系。NFA 这种转换图与之前的状态转换图很类似,但是区别是:同一个字符可以标记始于同一个状态的两个或多个转换,边上可以有输入字符符号,也可以有特殊符号 \(\epsilon\) 。
从正规表达式构造 NFA
这里采用一个简单的算法来实现这种构造。首先构造自动机使其能够识别任何 \(\epsilon\) 的字母表中的任何符号,然后由此构造自动机来识别包含一个交、一个连接或者一个克林闭包运算符的正规表达式。如对于正规表达式:a|b 可以先分别构造字符 a 和 b 的自动机,然后在从二者的 NFA 构造出 a|b 的 NFA。该算法被称为 Thompson 构造法。
自己实现一个 DFA 串模式识别器(二)的更多相关文章
- 自己实现一个 DFA 串模式识别器
自己实现一个 DFA 串模式识别器 前言 这是我编译原理课程的实验.希望读完这篇文章的人即便不知道 NFA,DFA 和正规表达式是什么,也能够对它们有一个简单的理解,并能自己去实现一个能够识别特定模式 ...
- WCF学习之旅—TCP双工模式(二十一)
WCF学习之旅—请求与答复模式和单向模式(十九) WCF学习之旅—HTTP双工模式(二十) 五.TCP双工模式 上一篇文章中我们学习了HTTP的双工模式,我们今天就学习一下TCP的双工模式. 在一个基 ...
- WCF学习之旅—HTTP双工模式(二十)
WCF学习之旅—请求与答复模式和单向模式(十九) 四.HTTP双工模式 双工模式建立在上文所实现的两种模式的基础之上,实现客户端与服务端相互调用:前面介绍的两种方法只是在客户端调用服务端的方法,然后服 ...
- MFC如何生成一个可串行化的类
一.MFC允许对象在程序运行的整个过程中持久化的串行化机制 (1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程. (2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构 ...
- OOAD-设计模式(二)之GRASP模式与GOF设计模式概述
一.GRASP模式(通用责任分配软件模式)概述 1.1.理解责任 1)什么是责任 责任是类间的一种合约或义务,也可以理解成一个业务功能,包括行为.数据.对象的创建等 知道责任——表示知道什么 行为责任 ...
- VC++ MFC如何生成一个可串行化的类
一.MFC允许对象在程序运行的整个过程中持久化的串行化机制(1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程.(2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构)的 ...
- 设计模式之代理模式之二(Proxy)
from://http://www.cnblogs.com/xwdreamer/archive/2012/05/23/2515306.html 设计模式之代理模式之二(Proxy) 0.前言 在前 ...
- python设计模式之常用创建模式总结(二)
前言 设计模式的创建模式终极目标是如何使用最少量最少需要修改的代码,传递最少的参数,消耗系统最少的资源创建可用的类的实例对象. 系列文章 python设计模式之单例模式(一) python设计模式之常 ...
- Java 设计模式之工厂模式(二)
原文地址:Java 设计模式之工厂模式(二) 博客地址:http://www.extlight.com 一.背景 本篇内容是 Java 设计模式创建型模式的第二篇.上一篇主题为 <Java 设计 ...
随机推荐
- Linux进程管理与性能监控
1. 进程管理工具 这一节我们介绍进程管理工具: 使用进程管理工具,我们可以查询程序当前的运行状态,或终止一个进程: 任何进程都与文件关联:我们会用到lsof工具(list opened files) ...
- JavaScript学习系列博客_19_JavaScript中方法(method)
方法 - 听了不少调用什么什么方法,所以方法究竟是啥东西? - 如果一个函数作为一个对象的属性保存,那么我们称这个函数时这个对象的方法,调用这个函数就说调用对象的方法(method). 创建一个对象 ...
- Micro LED巨量转移技术研究进展
近年来,Micro LED因其功耗低.响应快.寿命长.光效率高等特点,被视为继LCD.OLED之后的新一代显示面板技术.Micro LED的英文全名是Micro Light Emitting Diod ...
- OpenStack虚拟机virtaulinterfance 网络设备在libvirt的代码梳理
nova创建虚机网卡实际设备的代码调用流程为 _create_domain_and_network---->plug_vifs-->LibvirtGenericVIFDriver.plug ...
- 在使用postman中操作api接口测试403解决方法
在向Jenkins发送请求时收到了这样的403错误信息: No valid crumb was included in the request 后来通过google找到了解决方案. http://st ...
- koa-graphql express-graphql 中如何 定义每一个字段resolver执行函数
第一种方式: 首先来看一下,官方给出的koa-graphql的例子, ```js var express = require('express'); var {graphqlHTTP} = requ ...
- windows server 2008 r2 环境下,实现域名和IP同时都能访问一个网站
有时候,用域名访问能得到一个页面,用IP地址访问也可以得到一个页面,比如 www.baidu.com 和 61.135.169.125 都可以打开百度页面.一开始要实现这种功能,还真有点不知所措,想了 ...
- python yaml文件数据按原有的数据顺序dump
yml文件的更新后工具类: import os import yaml class YamlUtils(): def __init__(self,folder_name='config'): self ...
- 华为SEO搜索引擎主管招聘内容
http://www.wocaoseo.com/thread-166-1-1.html 华为SEO搜索引擎主管招聘内容: 职位职责 1. 提出全站的SEO策略和实施计划,推动和监督计划实施:负责提升各 ...
- 高可用集群之corosync+pacemaker
1.概念 在传统Linux集群种类,主要分了三类,一类是LB集群,这类集群主要作用是对用户的流量做负载均衡,让其后端每个server都能均衡的处理一部分请求:这类集群有一个特点就是前端调度器通常是单点 ...