自己实现一个 DFA 串模式识别器
自己实现一个 DFA 串模式识别器
前言
这是我编译原理课程的实验。希望读完这篇文章的人即便不知道 NFA,DFA 和正规表达式是什么,也能够对它们有一个简单的理解,并能自己去实现一个能够识别特定模式的串模式识别器。它可能会像是这样:
输入一个正规表达式:(s.f.l*.e)|(a*.b*)
输入:“sfe”
输出:matched!
输入:“sflea”
输出:failed!
注:'.' (点字符)表示连接运算
文章分为两部分,理论背景:介绍相关概念和原理;程序实现:使用 C++ 实现一个 DFA 串模式识别器。
理论背景
引入
我比较喜欢将任何理论和技术从自己能应用和理解的最低点开始阐述,因为这样往往可以将新的知识与过往的知识体系相联结。同时在一定的场景下思考它如何被应用,以切实的实现将所学流畅的抵达所用。这篇文章亦是如此。
首先我们要处理一个简单的问题,给出如下串:
例一:
ab,abab,ababab,abababab,...
a,aa,aaa,aaaa,...
aab,aabaab,aabaabaab,...
对于第一行给出的这些字符串,请问你是否能够编写简单程序,识别出给定的一个字符串 S 是否属于第一行中的某一个字符串?如 ab 属于第一行,abab 属于第一行,但 aab 不属于。我相信有过一定编程经验的人都可以通过简单的分支-循环逻辑,或者是一些字符串算法来写出一个判别程序。对于第二、三行也是如此。因为我们发现它们都具有一定的规律性,或者也可以称为遵循一定的模式。当情况很简单时我们并不用思考太多,只是不断的复杂化、堆叠我们的逻辑代码,希望代码逻辑能够捕获特定模式下所有的串。不过有时情况会很复杂,以至于我们非常困难去设计一个逻辑来实现判别(捕获模式)。比如下面这个串:
例二:
abb,aabb,babb,ababb,aaaaaaabb,bbbbbbbbabb,aababbababbbabbabb,
ababababaaaaaaabbbbbbbaaaaaaabbbbbaababbbabababbabbbbaabb,...
你可能会觉得这些串完全没有任何逻辑和规律可言嘛!没错,单凭对已给出的这些串很难发现规律。但是它确实有自己的模式,而且我可以提前告诉你,它们是由我根据正则(规)表达式:(a|b)*abb 产生的。如果你没有了解过正则(规)表达式也不必担心,先跳过它。
注:在某些不严格情况下,不区分正规表达式和正则表达式
模式串和正规表达式
在前文中,我重复了很多次模式这个词。其实我们之前看到的每一组串都是遵循特定的模式。非正式的,我们可以说 一组字符串构成的集合由一个与该组相关的称为模式的规则来描述。并且这个模式被说成匹配该集合中的每个字符串。
注:这里的模式特指 串的模式
可以 以例一为例介绍模式。非正式的表示:
例一的第一行的模式为:由 a、b 交替出现组成的串
第二行模式为:由若干个 a 组成的串
第三行模式为:由若干个 abb 组成的串
我们可以用自然语言描述简单的模式,但是无法去描述复杂的模式。所以就需要一种形式化的表示方法,来帮助我们表达。这就是正规表达式。正规表达式是表示模式的一种重要方法。每个模式匹配一个字符串集。简单来说,正规表达式需要一个字母表,其中字母表上的字符串是该字母表中符号的有穷序列。和定义在其上的一些运算。通过归纳已有的模式串,我们可以提出以下几种运算:
连接运算:以英文 '.' 表示。如:a.b 表示 串 ab
或运算:以英文 '|' 表示。如:a|b 表示串 a 或串 b
克林闭包运算:以英文 '*' 表示。如:a* 表示串:\(\epsilon\) ,a,aa,aaa,...
注:1. \(\epsilon\) 表示空串 2. 为了我的程序方便处理,我将连接运算设置成了 英文的点。
需要注意的是,运算并不止上述三种,但是我们主要讨论他们,并且很多运算可以通过它们复合得到。如:
正闭包:以英文:'+' 表示,当字母表只有 a 时 a+ 等价于 a.a*
? 运算:以英文:'?' 表示,当字母表只有 a 时 a? 等价于 (a|\(\epsilon\))
指数运算等
现在我们将例二中的正规表达式重新书写为:(a|b)*a.b.b 。参照上述运算的含义,我想你应该可以理解这个模式所代表的串的集合会是什么样的。
注意,正规表达式所能描述的模式是有限的。它只能表示固定次数的重复或给定结构没有指定次数的重复。它不能用于描述均衡或者嵌套结构。如具有括号配对的符号串集合正规文法无法描述,但是可以通过更复杂的上下文无关文法来描述。关于文法不作多描述。
出于篇幅考虑和更好的阅读体验,本文将分成三个部分,欢迎继续阅读余下篇章。下一篇内容是正规表达式的实现原理,涉及 NFA、DFA 的概念和相关算法。
作者:Skipper
出处:https://www.cnblogs.com/backwords/p/12726258.html
本博客中未标明转载的文章归作者 Skipper 和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
自己实现一个 DFA 串模式识别器的更多相关文章
- 自己实现一个 DFA 串模式识别器(二)
正规表达式的实现原理 上文讨论了串的模式的表达,即正规表达式.那么这一小节将讨论我们实现一个正规表达式的方法和原理.因为我们知道,一个正规表达式对应着一个串模式,而一个串模式又对应着一些列符合该模 ...
- MFC如何生成一个可串行化的类
一.MFC允许对象在程序运行的整个过程中持久化的串行化机制 (1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程. (2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构 ...
- 公布一个基于 Reactor 模式的 C++ 网络库
公布一个基于 Reactor 模式的 C++ 网络库 陈硕 (giantchen_AT_gmail) Blog.csdn.net/Solstice 2010 Aug 30 本文主要介绍 muduo 网 ...
- VC++ MFC如何生成一个可串行化的类
一.MFC允许对象在程序运行的整个过程中持久化的串行化机制(1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程.(2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构)的 ...
- python3 - 商品管理的程序,商品信息都存在一个json串里面
商品管理的程序,商品信息都存在一个json串里面 1.查询商品信息 #校验商品是否存在 2.新增商品 # #校验商品是否存在 #校验价格是否合法 3.修改商品信息 ##校验商品是否存在 if chic ...
- CREATE SCHEMA - 定义一个新的模式
SYNOPSIS CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ] CREATE SCHEM ...
- ZZNU-oj-2141:2333--【O(N)求一个数字串能整除3的连续子串的个数,前缀和数组+对3取余组合数找规律】
2141: 2333 题目描述 “别人总说我瓜,其实我一点也不瓜,大多数时候我都机智的一批“ 宝儿姐考察你一道很简单的题目.给你一个数字串,你能判断有多少个连续子串能整除3吗? 输入 多实例输入,以E ...
- 【基本算法】 KMP文本串模式串的字符串匹配算法
看了两个晚上的KMP,加上基本的“暴力匹配” 今晚看懂next[j]递归求解时,突然觉得算法真的好美妙,虽然觉悟的晚但晚胜过没有是吧! 我的博客都是应试性的学习笔记,不具备指导性,还是大神们写的好,例 ...
- BF算法(串模式匹配算法)
主串和子串 主串与子串:如果串 A(如 "shujujiegou")中包含有串 B(如 "ju"),则称串 A 为主串,串 B 为子串.主串与子串之间的关系可简 ...
随机推荐
- 为我开发的API添加华丽的外衣
在日常开发中,最容易被吐槽的就是代码写的烂,没有注释鬼知道你这个是什么意思啊? 另一个就是文档不齐全,这些接口是干嘛的?参数是什么意思?等等问题. 归根到底还是没有严格的开发规范,最重要的还是要有方便 ...
- 手把手教你用GoEasy实现Websocket IM聊天
经常有朋友问起GoEasy如何实现IM,今天就手把手的带大家从头到尾用GoEasy实现一个完整IM聊天,全套代码已经放在了github. 今日的前端技术发展可谓百花争鸣,为了确保本文能帮助到使用任何技 ...
- JSP+Servlet+C3P0+Mysql实现的网上蛋糕店
本文存在视频版本,请知悉 项目简介 项目来源于:https://gitee.com/PositiveMumu/CakesShop/tree/master 这次分享一个蛋糕商场系统,还是很简单的系统.界 ...
- if-else代码优化的八种方案
前言 代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案. 优化方案一:提前return,去除不必要的else 如 ...
- AI领域:如何做优秀研究并写高水平论文?
来源:深度强化学习实验室 每个人从本科到硕士,再到博士.博士后,甚至工作以后,都会遇到做研究.写论文这个差事.论文通常是对现有工作的一个总结和展示,特别对于博士和做研究的人来说,论文则显得更加重要. ...
- 累加数的贡献 CodeForces - 1213D2
题意: 第一行输入n,k,表示有n个数,可以进行整除2操作,要是数组有k个相等的数,最少需要几次操作. 思路: 用一个数组记录每一个数出现的次数,如果一开始大于等于k,直接输出0,否则对这n个数进行从 ...
- coding++:使用 javascript 在html中获取url参数
函数处理定义如下: < script type = "text/javascript" > function $G() { var Url = top.window.l ...
- Mongodb中 数据库和集合的创建与删除
1.查询数据库,查询表: show dbs //查询所有的数据库show collections //查询所有的集合(表) 2.创建数据库或切换到数据库(存在就切换,不存在就创建) use spide ...
- 20175314 《Java程序设计》第十一周学习总结
20175314 <Java程序设计>第十一周学习总结 教材学习内容总结 URL类 URL类是java.net包中的一个类,用URL创建的对象可以获取URL中的资,其包括三部分信息:协议. ...
- linux压缩及归档
一.解析 压缩:把大文件,通过压缩成一个比之前小的文件. 归档(打包):把多个文件,归档成一个文件. 二.压缩 1.zip(归档压缩,可以压缩目录,要保存源文件) 压缩:zip 压缩后的文件名 压缩 ...

