从FSM到正则表达式

  本文以一个有限状态自动机(FSM)为例来介绍几种从有限状态自动机转化为正则表达式的方法。

  有一个FSM能接受能被3整除的二进制串(如字符串0,其十进制为0(考虑其到初始状态,认为读到0,亦为可接受状态);字符串11,其十进制为3;字符串110,其十进制为6;......这些都可接受)。这个有限自动机的图形表示如图1所示:

下面讲叙将图1所表示的FSM转化为正则表达式。

第一种方法,从实质出发:

其实质为:从A状态出发经过若干次(包括0次)转移(途径),最终恰好回到状态A。所谓求正则表达式,即对这些转移(途径)进行归纳。

从总体考虑比较复杂,所以可以考虑动态规划的思想。

这是一种很基础的方法,即从其定义实质出发,也是一种麻烦的方法,在这里不准备讲解。对于这种方法,在《自动机理论、语言和计算导论》一书上有较为详细的讨论。

第二种方法,消结消弧法:

所谓结即为状态,弧即为输入字符(或者转移途径)。

注意图2中红色标记的弧,将会被消除。如何消除?将其等效替换掉。红色标记弧表示A状态接受字符1将转移到状态B,我们继续考虑当接受下一个字符时将转移到的状态:当接受0时,转到B;当接受1时,转到A。所以我们可以如下等效替换如图3:

同理再将图3中的红色标记的弧消除,得到如图4所示:

由于图4中的状态B无论如何也不能通过转移达到,所以状态B可以省略,即消除结点。则得图5:

说明:状态A读到ε,依旧为接受态,认为ε为可接受字符串。从图5中可以轻易得出集合{ε,0,11,10(1,00)*01}*为可接受状态集合。可将形式改写为{ε|0|11|10(1|00)*01}*这个式子看起来比较繁杂,还可以略作等价改写。

第三种方法:转化为正则表达式方程组求解:

要用到的定理:设α,β为已知正则表达式,x是未知正则表达式,那么x=α*β是正则表达式方程

x=αx+β                          <1>

的一个解,当ε∉L(α)时,x=α*β是表达式方程<1>的唯一解。

先不考虑ε,如图1所示写出对应的正则文法:

A->0A|1B|0

B->1A|0C|1

C->1C|0B

这样就可得到对应的正则表达式方程组:

A=0A+1B+0       ①

B=1A+0C+1       ②

C=1C+0B     ③

对③用定理得C=1*0B,将其代入②,再用定理得B=(01*0)*(1A+1),又将其带入 ①,并用定理得

(0+1(01*0)*1)*(0+1(01*0)*1),考虑到ε,将式子整理

可得结果为(0+1(01*0)*1)*,与方法二的结果其实是一样的。

时间: 2024-10-09 07:15:00

从FSM到正则表达式的相关文章

CSV文件格式解析器的实现:从字符串Split到FSM

本文分为5小节,基本上就是我刚接触CSV文件到思考.实践做一个CSV解析器的过程的还原.希望我的思路也能带领你一步步从浅到深认识CSV文件格式. 1.简单的CSV解析器实现. 2.简单实现的CSV解析器的问题 3. CSV格式的定义 4.用FSM(有限状态机)来做CSV格式解析. 5.为什么使用CSV格式 1.简单的CSV解析器实现. 最近有一个需求,读取CSV格式的配置.CSV是CommaSeparated Value(逗号分隔值)的缩写,通常用文本表示数据.CSV格式数据的结构类似表格,不同

Atitit. 有限状态机 fsm 状态模式

Atitit. 有限状态机 fsm 状态模式 1. 有限状态机 1 2. "状态表"和"状态轮换表" 1 3. 有限状态机概念(状态(State)事件(Event)转换(Transition) 动作(Action) 2 4. 状态机的应用场景 2 4.1. ,"有限状态机"在游戏的人工智能方面是很有用处的. 2 4.2. 用状态机模式消除复杂的 if else 逻辑 2 4.3. 源码文本处理状态机 2 4.4. 正则表达式(regexp),判断

算法学习笔记(九)有限状态机 FSM 的应用

一个问题:Beautiful String 这是2014微软校招的编程题,题意大致如下: 如果一个字符串包括三组或者更多组的连续升序字母,每组长度相等,那么我们就称这个字符串是Beautiful String 符合Beautiful String举例:abc, cde, aabbcc, aaabbbccc 不符Beautiful String举例:abd,cba,aabbc,zab 输入一个只含有小写字母的字符串,如果它含有一个Beautiful的子串,就输出YES,否则输出NO 输入: 第一行

【Linux系列】【基础版】第四章 Shell基础之正则表达式

4. Shell基础之正则表达式     4.1 正则就是一串有规律的字符串         4.1 grep              4.1.1 格式: grep [-cinrvABC] 'word' filename             4.1.2 -c //count,表示行数             4.1.3 -i //不区分大小写             4.1.4 -n  //显示行号             4.1.5 -r  //遍历所有子目录             4

正则表达式中的逆向思维

人们的正常思维都是顺向的,那么逆向思维呢,特别是初学正则表达式的同学们,好不容易掌握了正则表达式的用法,再突然要你用逆向思维做题,会有很多不适应: 这里拿三道题,来做简单介绍: 1.经典例题取IP: [[email protected] ~]# ifconfig eth0|sed -nr '2s#^[^0-9]+(.*)[a-Z]{5,}.*#\1#gp' 10.0.0.200 2.调换/etc/passwd中最后一列和第一列的位置: [[email protected] ~]# head /p

JAVA正则表达式:Pattern类与Matcher类详解(转)

java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包.它包括两个类:Pattern和Matcher Pattern 一个Pattern是一个正则表达式经编译后的表现模式. Matcher 一个Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查. 首先一个Pattern实例订制了一个所用语法与PERL的类似的正则表达式经编译后的模式,然后一个Matcher实例在这个给定的Pattern实例的模式控制下进行字符串的匹配工作

前端学PHP之正则表达式函数

前面的话 正则表达式不能独立使用,它只是一种用来定义字符串的规则模式,必须在相应的正则表达式函数中应用,才能实现对字符串的匹配.查找.替换及分割等操作.前面介绍了正则表达式的基础语法,本文将详细介绍正则表达式函数 匹配与查找 [preg_match()] preg_match()函数用来执行一个正则表达式匹配,搜索subject与pattern给定的正则表达式的一个匹配.返回pattern的匹配次数.它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后将会停止搜索.preg

正则表达式

grep命令和正则表达式 一. 正则 : 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个"规则字符串",这个"规则字符串"用来表达对字符串的一种过滤逻辑.给定一个正则表达式和另一个字符串,我们可以达到如下的目的:1. 给定的字符串是否符合正则表达式的过滤逻辑(称作"匹配"):2. 可以通过正则表达式,从字符串中获取我们想要的特定部分. 正则表达式和通配符一样,也是一组特殊符号,通配符是由sh

java中的正则表达式

正则表达式 : 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串.将匹配的子串替换或者从某个串中取出符合某个条件的子串等. 一些字符所代表的意思: \        将下一字符标记为特殊字符.文本.反向引用或八进制转义符^       匹配输入字符串开始的位置$       匹配输入字符串结尾的位置.        匹配任何单个字符\s      空白(空格符.换行符.回车符.制表符)\S     非空白[]