我正在尝试为带有字母a,b,c的语言编写正则表达式查询,使得a永远不会与b相邻。
可以通过仅使用交替(加号),连接和重复(乘法)运算符来完成吗?
L = w属于{a,b,c} *,因此a永远不会与b
相邻答案 0 :(得分:5)
(让我们看看我是否回想起足够的形式语言理论。)
这样的正则表达式可以在DFA的帮助下构建:
A = aA + cC + F // only a or c can follow a
B = bB + cC + F // only b or c can follow b
C = cC + aA + bB + F // any char can follow c
A
,B
和C
是表示a
时的状态的状态,b
和c
分别是前一个字符。由于任何字符都可以跟c
,因此我们可以将C
作为开始状态。 F
是最终结束状态(字符串结束)。
此DFA可以转换为正则表达式,如下所示:
A = a*(cC+F) // eliminate recursion
B = b*(cC+F) // eliminate recursion
C = cC + aA + bB + F
= cC + aa*(cC+F) + bb*(cC+F) + F // substitute A and B
= (c + aa*c + bb*c)C + aa*F + bb*F + F // regroup
= (c + aa*c + bb*c)*(aa*F + bb*F + F) // eliminate recursion
= (c + aa*c + bb*c)*(aa* + bb* + e)F // regroup
所以表达式是:
(c + aa*c + bb*c)*(aa* + bb* + e) // e being the empty/null string
或以非正式的正则表达式格式:
(c|a+c|b+c)*(a+|b+)?
可以缩短为:
(a+c|b*c)*(a*|b*)