正则语言的定义#
正则语言是在有限字母表 Σ 上的一个集合,其中包含的元素是所有能被一个正则表达式/DFA/NFA识别的字符串,正则语言是Σ∗的一个子集
正则表达式的定义#
正则表达式是一个字符串,使用特定的语法规则来描述一个正则语言。正则表达式和DFA、NFA之间是等价的,即它们识别的正则语言是相同的
正则表达式⇔DFA⇔NFA 正则表达式由以下基本元素组成,且以下每个元素本身也是一个正则表达式:
- 空集:表示一个不包含任何字符串的语言,通常用符号 ∅ 表示
- 空字符串:表示一个只包含空字符串的语言,通常用符号 ϵ 表示
- 单个符号:对于每个输入符号 a∈Σ,表示一个只包含字符串 a 的语言
- 连接:如果 R 和 S 是正则表达式,那么 RS 表示连接操作,表示由 R 中的字符串连接 S 中的字符串组成的语言,或多次连接,例如 Rn 表示由 R 中的字符串连接 n 次组成的语言,R0={ϵ}
- 选择:如果 R 和 S 是正则表达式,那么 R∣S 表示选择操作,表示由 R 中的字符串或 S 中的字符串组成的语言
- 闭包:如果 R 是一个正则表达式,那么 R∗ 表示闭包操作,表示由 R 中的字符串重复零次或多次组成的语言
一个正则表达式通过有限次上述操作后生成的仍然是一个正则表达式,因此正则表达式可以递归定义
TIP正闭包:R+ 表示由 R 中的字符串重复一次或多次组成的语言,即 R+=RR∗
克林闭包:R∗ 表示由 R 中的字符串重复零次或多次组成的语言,即 R∗={ϵ}∪R+
运算顺序:括号 > 闭包 > 连接 > 选择
设计一个正则表达式匹配所有包含110但不能包含111的二进制字符串
可以使用以下正则表达式:
(0+10)∗110(110+0+10)∗(1+11+ϵ)
DFA/NFA转正则表达式#
e.g. 现有一DFA,状态转移表如下:
| 状态 | 输入0 | 输入1 |
|---|
| →q0 | q1 | q0 |
| q1 | q2 | q0 |
| ∗q2 | q2 | q2 |
状态消除法#
- 添加唯一的开始状态和接受状态(实际上这么处理完已经变NFA了):
| 状态 | 输入0 | 输入1 | ϵ |
|---|
| →S | - | - | q0 |
| q0 | q1 | q0 | - |
| q1 | q2 | q0 | - |
| ∗q2 | q2 | q2 | F |
| ∗F | - | - | - |
- 逐个消除中间状态:
经过步骤1后,中间状态是q0和q1,我们可以先消除q2:
关注要消除的状态的入边、自环和出边,将其替换为一个新的正则表达式,公式为:
入边表达式⋅(自环表达式)∗⋅出边表达式+入边来源到出边目标原有表达式
- q2入边:q10q2,则表达式为0
- q2自环:q20q2,q21q2,则表达式为0+1
- q2出边:q2ϵF, 则表达式为ϵ
所以消去q2后,只有一个来源和一个目标,则只有q1到F的边,q1到F的表达式为:
0(0+1)∗ϵ+无=0(0+1)∗ 当前状态转移为:
Sϵq0,q00q1,q11q0,q01q0,q10(0+1)∗F 消q1:
- 入边:q00q1,则表达式为0
- 自环:q1没有自环,则表达式为ϵ
- 出边:q10(0+1)∗F,q11q0,则表达式有0(0+1)∗与1
则q0到F的表达式为:
0⋅(ϵ)∗⋅0(0+1)∗+∅=00(0+1)∗ q0到q0的表达式为:
注意q0到q0已存在转移(自环),不要忘记并上
0⋅(ϵ)∗⋅1+1=01+1 此时,状态转移为:
Sϵq0,q001+1q0,q000(0+1)∗F 消q0:
- 入边:Sϵq0,则表达式为ϵ
- 自环:q001+1q0,
- 出边:q000(0+1)∗F,则表达式为00(0+1)∗
则S到F的表达式为:
ϵ⋅(01+1)∗⋅00(0+1)∗+∅=(01+1)∗00(0+1)∗ 则结果为:(01+1)∗00(0+1)∗
Rij(k)递推法#
首先为每个状态标注序号(给的DFA已经有了可以直接用),则Rij(k)表示从状态i到状态j,经过的所有中间状态(中间也就是不包含开始和结束状态)的序号不超过k的所有路径的正则表达式。
也就是如果想得到上述DFA的正则表达式,我们需要计算R02(2)
递推公式#
Rij(k)=Rij(k−1)+Rik(k−1)(Rkk(k−1))∗Rkj(k−1) 含义为:
Rij(k)=+⋅⋅不经过状态k就能从状态i到达状态j的所有路径能从i到达状态k但不经过k的所有路径(状态k的自环)∗从状态k到达状态j但不经过k的所有路径 开始递推:
R02(2)R02(1)R22(1)R01(0)R11(0)=R02(1)+R02(1)(R22(1))∗R22(1)=R02(0)+R01(0)(R11(0))∗R12(0)=∅+R01(0)(R11(0))∗0=R22(0)+R22(0)(R22(0))∗R22(0)=(0+1)∗+(0+1)∗((0+1)∗)∗(0+1)∗=(0+1)∗=R01(−1)+R00(−1)(R00(−1))∗R01(−1)=0+1⋅(1)∗⋅0=1∗0=R11(−1)+R10(−1)(R00(−1))∗R01(−1)=∅+1⋅(1)∗⋅0=11∗0 所以:
R02(1)R22(1)R02(2)=1∗0(11∗0)∗0=(0+1)∗=R02(1)+R02(1)(R22(1))∗R22(1)=1∗0(11∗0)∗0+1∗0(11∗0)∗0((0+1)∗)∗(0+1)∗=1∗0(11∗0)∗0(0+1)∗