我需要为这种语言创建一个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,因为我可以在正则表达式测试网站上轻松测试它。但这也行不通。我最终得到了太多看似没有尽头的组合。
我不知道如何在不使用某种计数机制的情况下为其创建正则表达式。 有人可以给我一个暗示吗?
答案 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
。