需要具备的只是 编译原理 前第三章(词法分析,大概花个17个课时就可以了,读者要是感兴趣的话,可以多多深入了解)东南大学 廖力老师的编译原理很不错,推荐读者自己看看,(考前同学可以看看)
基本概念讲解
即如下知识
- 正规集,在编译原理中叫做 语言-> L ( α ) L(\alpha) L(α) ,也就是说有句子的集合(这里要对句子有个非常清晰的理解,句子就是符合语法规则的字符串(更准确地应该叫做终结符组合而成字符串)),也可以理解为 在树叶子节点组成的集合,在被3整除的所有能表示的数字串组成的集合就是在这个应用场景下的正规集:
非被3整除的句子有: 112 ,11111,12311。。。
被3整除的句子有: 111, 132, 13599。。。
- 字母表,可以理解为 ascii码中的所有字符集合,也可以理解成英语中的26个字母,因为所有单词都是都是从这个字母表中的字符组合而成的,通常用 ϵ \epsilon ϵ代表空串,一般理解为开始符和结束符阶段,当然也可以在任一状态都可以使用 ϵ \epsilon ϵ代表自身,不过这有点没有多少意思,反而会使得自动机转向不确定,徒增编码难度:
更准确的说法是,在一个问题空间中,所构成终结符的元素,而这些元素不可再分
- 状态集,包括三种
a) 初始状态 S S S (start)来表示,也就是程序的主入口,或者计算机方法或者函数的参数列表
b)中间状态 ,可以由终结符和非终结符共同组成,用来表示非结束状态的中间生成过程的状态
c)结束状态 Z Z Z, (Z是字母表种最后面的)
在编译原理中也叫做 V V V ∈ V T V_T VT∪ V N V_N VN,其中
V T V_T VT 表示终结符(terminal symbol),即对应到编译原理中的词法分析中的所有单词或者语法分析中的所有句子。
V N V_N VN 表示非终结符(Nonterminal symbol),在语法分析中,使用到的中间表达过程,比如语法单位:《谓语》《主语》词法单位:《名词》 《动词》都是属于中间状态,这些状态对正规集中的每一个元素的一种抽象的描述,方便我们组合成表达式,或者生成式
- 转移方程,也可叫做映射方程组,在编译原理中叫做生成式组,在数学中叫做函数(联立方程组),其实指的都是一个东西,转换的方式或转换的过程,用 F F F表示,表达了 x x x状态可以通过转移方程转化到 y y y状态。
根据映射方程或者函数的单射和非单射分两种类型的有限自动机
a) 单射函数对应的是 确定性(deterministic)的有限自动机(DFA),因为每一种状态到下一步的转化通过单射(有且只能转化成一个固定的状态)进行映射,也就是边的方向是唯一确定的。而
b) 不确定性有限自动机(NFA),与DFA恰恰相反,一般来说,根据定理 我们可以通过一种算法使得 NFA 转换到DFA,也就是NFA确定化方法(子集法等)生成DFA,并对DFA进行简化成一个最优DFA,方便我们编程,因为在DFA中有些状态可能是等价的,要进行合并,一般通过分裂法进行分裂
有限状态机
以下是有限状态机五元式方法的最重要的几个概念用一张图来表示有限状态机做如
图1.1
我们可以用图的方式能够代表
-
语言集,也就是非计算机人所要表达的话,或者说是输入数据集,因为,在计算机的世界中,计算机是不清楚人讲的是什么的,因此我们用外部代表语言集。
-
M 有限自动机,这个可以理解为是一个真正的计算机,里面的所有规则,状态,转换方程都是计算机能够理解的,或者说用这个图,我们可以翻译成计算机程序,让计算机编程一个自动机的样子或者说是一个自动机器人那样。图中的只有一个圈的代表非终结符,两个圈圈的表示为终结符。 f 1 f1 f1, f 2 f2 f2, f 3 f3 f3, f 4 f4 f4分别为转换方程组中的方程,可以理解为if(遇到f1的条件){then 从 0 状态转化到1状态},在词法分析部分, f 1 f1 f1, f 2 f2 f2, f 3 f3 f3, f 4 f4 f4代表了遇到的每个字符的(a,b,c),即遇到“a”字符应该走哪个方程的意思
-
输出结果,也就是最后让自动机回复的输出内容。通常,有如下两个方式结束(不符合规范,或不符合文法集,或不符合转移方程组)判断
a) 在自动机状态转移过程中,遇到了一个状态无法正常通过转移方程进行转化
b) 在判断 ϵ \epsilon ϵ最终程序停在非终结符的时候代表着程序失败,输出错误信息,反之能够根据这个去欸的那个
图,直观理解
我们可以发现这个图其实描述的是一个确定性有限自动机的过程,因为每个状态通过特定 f f f转移方程都能够唯一确定一个状态节点。下图就是一个非确定性自动机,因为 状态1号通过 f 2 f2 f2 方程可以走向状态0或状态2,用图表示就更直观,因为这个图是给人看的。
图1.2
矩阵思路
状态id\转移方程 | f 1 f1 f1 | f 2 f2 f2 | f 3 f3 f3 | f 4 f4 f4 |
---|---|---|---|---|
0 | 1 | / | / | / |
1 | / | 0,2 | / | 1 |
2 | / | / | 3 | 1 |
3 | / | / | / | / |
通过把根据图1.2的非确定性有限自动机让我们人来看是非常直观的,那对于计算机来说不太友好,为了解决计算机识别的问题,往往通过转化成矩阵的形式,这个也是翻译成程序的一个非常直观的方法,读者试着用if else等程序语言写写这个自动机,是不是很简单呢?是的,我们可以直接用双手敲出一些逻辑表达式来实现有限状态机,不需要多么高深的理论,不过仅限于确定型有限自动机。
进入话题
在今天我将的主题,用正则表达式来表示一个被3整除的数字串,其实这个问题是我在几年前看到的一篇知乎文章,使用到的是有限自动机。
我们需要确定以上这四个点
-
寻找正规集,也就是句子
这个主题中的正规集是什么?很简单,比如
{ 111 , 123 , 3 , 144126 , 6 , 522 , . . . } \lbrace{ 111 , 123 , 3,144126 ,6,522,...\rbrace} {111,123,3,144126,6,522,...}
所能表示的所有能被3整除的数字串的集合,也就是数学定义中的空间集合 -
定位字母表
字母表是什么? 其实这里的字母表就是
{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } \lbrace{ 0,1,2,3,4,5,6,7,8,9\rbrace} {0,1,2,3,4,5,6,7,8,9}
所有能组成正规集元素的最小组成集合 -
寻找状态集合
状态集是什么?这里就是比较有技巧的地方,也是最难定位的一个地方,俗话说得好,解决问题的方法永远比难题本身还要多,而这个方法就是我们要去探索、吸取、总结以及创新的地方。不过有个比较取巧的方法(套路)是我们从一点一点试探的过程中总结出,不可能一蹴而就的。
但是有个比较好的方式,先寻找转移方程,然后再确定状态集合,学过深度学习的同学会发现,这里的状态集合像极了神经元,我们不知道神经元是什么,但是我们却能通过权重的调整使得模型达到无限接近于现实。那么这里的权重像极了转移方程 -
转移方程式什么
首先,我们可以简单把字母表中的字母作为转移方程的分段函数,也就是定位了10个分段函数,不知是哪位教授说起过,人们认识事物的直接方式是分段函数,然后不断优化?,
其次,合并同一性质的分段函数,通过找规律,我们可以把{0,3,6,9},{1,4,7},{2,5,8} 作为分段三组分段,每一分段,都是随机产生的,你也不知道下一步是哪个分段。当然在某种意义上来看分段,使得人们思考问题的方式更加精简,也就达到了飞的感觉
最后 画出 如下的状态转移图,盗个图。。
-
如何进行状态机与正则表达式之间进行转换。
这个技术是通用的,先写到这,有时间再写哈