自己实现一个 DFA 串模式识别器

前言

这是我编译原理课程的实验。希望读完这篇文章的人即便不知道 NFA,DFA 和正规表达式是什么,也能够对它们有一个简单的理解,并能自己去实现一个能够识别特定模式的串模式识别器。它可能会像是这样:

  1. 输入一个正规表达式:(s.f.l*.e)|(a*.b*)

  2. 输入:“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 串模式识别器的更多相关文章

  1. 自己实现一个 DFA 串模式识别器(二)

    正规表达式的实现原理 ​ 上文讨论了串的模式的表达,即正规表达式.那么这一小节将讨论我们实现一个正规表达式的方法和原理.因为我们知道,一个正规表达式对应着一个串模式,而一个串模式又对应着一些列符合该模 ...

  2. MFC如何生成一个可串行化的类

    一.MFC允许对象在程序运行的整个过程中持久化的串行化机制 (1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程. (2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构 ...

  3. 公布一个基于 Reactor 模式的 C++ 网络库

    公布一个基于 Reactor 模式的 C++ 网络库 陈硕 (giantchen_AT_gmail) Blog.csdn.net/Solstice 2010 Aug 30 本文主要介绍 muduo 网 ...

  4. VC++ MFC如何生成一个可串行化的类

    一.MFC允许对象在程序运行的整个过程中持久化的串行化机制(1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程.(2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构)的 ...

  5. python3 - 商品管理的程序,商品信息都存在一个json串里面

    商品管理的程序,商品信息都存在一个json串里面 1.查询商品信息 #校验商品是否存在 2.新增商品 # #校验商品是否存在 #校验价格是否合法 3.修改商品信息 ##校验商品是否存在 if chic ...

  6. CREATE SCHEMA - 定义一个新的模式

    SYNOPSIS CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ] CREATE SCHEM ...

  7. ZZNU-oj-2141:2333--【O(N)求一个数字串能整除3的连续子串的个数,前缀和数组+对3取余组合数找规律】

    2141: 2333 题目描述 “别人总说我瓜,其实我一点也不瓜,大多数时候我都机智的一批“ 宝儿姐考察你一道很简单的题目.给你一个数字串,你能判断有多少个连续子串能整除3吗? 输入 多实例输入,以E ...

  8. 【基本算法】 KMP文本串模式串的字符串匹配算法

    看了两个晚上的KMP,加上基本的“暴力匹配” 今晚看懂next[j]递归求解时,突然觉得算法真的好美妙,虽然觉悟的晚但晚胜过没有是吧! 我的博客都是应试性的学习笔记,不具备指导性,还是大神们写的好,例 ...

  9. BF算法(串模式匹配算法)

    主串和子串 主串与子串:如果串 A(如 "shujujiegou")中包含有串 B(如 "ju"),则称串 A 为主串,串 B 为子串.主串与子串之间的关系可简 ...

随机推荐

  1. CVE-20117-111882漏洞复现及利用

    背景 工程实践题目: 渗透方向:实验班要求 1.利用已有的漏洞,搭建内网实验环境(WEB漏洞或系统漏洞以近两年内的CVE编号为准,每人一个,先报先得,具体由学习委员负责协调),利用工具进行内网渗透攻击 ...

  2. 【开发工具 docker】值得学习的应用容器引擎docker安装

    概述: Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何 ...

  3. HTTP2.0学习 与 Nginx和Tomcat配置HTTP2.0

    目录 一.HTTP2.0 1.1 简介 1.2 新的特性 1.3 h2c 的支持度 二.Nginx 对 http2.0 的支持 2.1 Nginx 作为服务端使用http2.0 2.2 Nginx 作 ...

  4. 为什么 select count(*) from t,在 InnoDB 引擎中比 MyISAM 慢?

    统计一张表的总数量,是我们开发中常有的业务需求,通常情况下,我们都是使用 select count(*) from t SQL 语句来完成.随着业务数据的增加,你会发现这条语句执行的速度越来越慢,为什 ...

  5. 关于手机淘宝3.25bug我的一些思考与建议

    这两天被手淘ios版3.25bug刷屏了,影响还是挺大的,仅3.25日当天截止到下午5点在微博上的话题阅读量,已经突破8000万.给广大网友带来一次吃瓜盛宴.我们先简单回顾下这个bug的故事线: 我查 ...

  6. 【Code Force】Round #589 (Div. 2) D、Complete Tripartite

    题目链接 大致题意 把一个图分成三块,要求任意两块之间是完全图,块内部没有连线 分析 首先根据块内没有连线可以直接分成两块 假定点1是属于块1的,那么所有与点1连接的点,都不属于块1:反之则是块1的 ...

  7. elasticsearch和kibana安装后,外网无法访问

    问题描述: 现在解压elasticsearch之后,启动,通过http://localhost:9200可以访问的到,但是http://ip:9200访问不到 解决方法: 修改elasticsearc ...

  8. JUC 中提供的限流利器-Semaphore(信号量)

    在 JUC 包下,有一个 Semaphore 类,翻译成信号量,Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源.Semaphore 跟锁 ...

  9. Colab笔记本能用英伟达Tesla T4了,谷歌的羊毛薅到酸爽

    谷歌出品的Colab笔记本,机器学习界薅羊毛神器,如今又有了新福利: 连英伟达最新一代机器学习GPU:Tesla T4都能免费蹭,穷苦羊毛党也顿时高端了起来. 英伟达的Tesla T4,是去年秋天才发 ...

  10. 模块 序列化 json pickle shelv xml

    序列化 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes. json 模块 json.dump(d,f) json.load(f ...