正则表达式为'a'和'b'的串联单词。 a在一个单词中恰好出现n * 2次,而'b'正好出现n * 3次

时间:2013-11-17 21:18:05

标签: regex automaton

我需要为这种语言创建一个NFA(或DFA,不知道它将会是哪一个):

L(A) = { w ∈ {a,b}* | count(w, a) = 2i, count(w, b) = 3j, i, j ∈ ℕ }

count(w,z)定义字母z出现在单词w中的频率。在这种情况下,对于'a',它是2的倍数,对于'b',它是3的倍数。

有效词的例子:babab,aabbb,bbaab,bbbabbba

我努力为此创建一个自动机,所以我想我首先尝试为它创建一个正则表达式,然后使用this method将其转换为NFA,因为我可以在正则表达式测试网站上轻松测试它。但这也行不通。我最终得到了太多看似没有尽头的组合。

我不知道如何在不使用某种计数机制的情况下为其创建正则表达式。 有人可以给我一个暗示吗?

3 个答案:

答案 0 :(得分:5)

您可以将自动机建模为六种不同的状态,每种状态描述(count(w,a)mod 2,count(w,b)mod 3)的状态。有六种不同的可能状态:

(0,0) (0,1) (0,2) (1,0) (1,1) (1,2)

每当你读到“a”时,你就会从当前状态(例如(0,1))进入下一个相应的状态( - >(1,1))。如果你读了另一个“a”,你又回到了同一个状态( - >(0,1))。与“b”相同,但改变b值(例如(0,1) - >(0,2) - >(0,0) - >(0,1))。

唯一允许的接受状态是(0,0)。

使用视觉符号:

http://cdn.imghack.se/images/ccea2c62451d81e477f73ac6fabc5134.png

答案 1 :(得分:0)

让我们看看,你需要一个偶数个,给你两个状态

a-even
a-odd

你需要b的倍数为三倍:

b-ok
b-one
b-two

结合这些状态,我们可以构建以下语法:

S(*) -> a A | b B1
A -> a S | b B1A
B1 -> b B2 | a B1A
B1A -> a B1 | b B2A
B2 -> b S | a B2A
B2A -> a B2 | b A

所以,这是一个常规语法,所有规则都有一个终端simbol和最多一个非终端的正确递归,希望语法有所帮助。

答案 2 :(得分:0)

验证输入的最简单方法是根据您的要求使用正则表达式:

^(?=((b*a){2})*b*$)(?=((a*b){3})*a*$)[ab]*$

这使用预测来断言“a”的数量是2的倍数(包括零),类似地,对于“b”,如果为3则带来s倍。

使用您的示例和一些无效示例,查看此正则表达式的live demo