a,b,c上的语言的正式正则表达式,使得a永远不会与b相邻

时间:2012-01-31 07:15:03

标签: regex formal-languages

我正在尝试为带有字母a,b,c的语言编写正则表达式查询,使得a永远不会与b相邻。

可以通过仅使用交替(加号),连接和重复(乘法)运算符来完成吗?

L = w属于{a,b,c} *,因此a永远不会与b

相邻

1 个答案:

答案 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

ABC是表示a时的状态的状态,bc分别是前一个字符。由于任何字符都可以跟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*)