我正在练习DFA,我遇到了这个看似非常复杂的问题。我尝试将它分成两个较小的问题,我有一个答案,但它看起来不对我。
有人可以帮助我,或者至少给我一些提示。
我能想到的另一种可能性是,你每两个O或1只有一个接受状态,因为它们需要成对。因此例如11接受11接受11接受。
答案 0 :(得分:3)
您将状态机描述为一幅巨大的图片,但您可以通过使用结构化名称命名状态而不是尝试绘制巨大的图表来更轻松地解决问题。
让你的状态为(n,m,s),其中n是你看过的00的数量,m是你看过的11s的数量,s是前面的字符读数(s ='',' 1','0')(其中''表示你没有看到过前一个角色,或者你刚刚找到'00'或'11')。
然后你的过渡是:
(n, m, '') -0-> (n, m, '0')
(n, m, '') -1-> (n, m, '1')
(n, m, '0') -0-> (n+1, m, '')
(n, m, '0') -1-> (n, m, '1')
(n, m, '1') -0-> (n, m, '0')
(n, m, '1') -1-> (n, m+1, '')
n <= 2且m <= 3的所有状态都在接受。开始状态为(0, 0, '')
。
这不是有限的,但你可以通过将所有非接受状态合并为一个状态来实现。它将具有(3 * 4 * 3 + 1)= 37个状态,这是最小的。
上面的答案假设'000'包含一个'00'而不是2'00'(即'00'的数字是字符串中非重叠'00'的最大数量,并且相同' 11' )。如果你想把'000'算作2,你需要这台机器:
状态是S(开始)或(n,m,s),其中n,m和以前一样,s是'0'或'1'。然后:
S -0-> (0, 0, '0')
S -1-> (0, 0, '1')
(n, m, '0') -0-> (n+1, m, '0')
(n, m, '0') -1-> (n, m, '1')
(n, m, '1') -0-> (n, m, '0')
(n, m, '1') -1-> (n, m+1, '1')
所有州都接受,但n> 2或m> 3的州除外。同样,我们将所有不接受状态合并为一个状态。
这有(3 * 4 * 2 + 2)= 26个状态,这也是最小的。
鉴于正式描述,可以编写程序来生成描述机器的DOT文件。这是在答案的第一部分为机器生成图表的程序。 (注意,它没有显示哪些州正在接受,但它们都是FAIL除外)。
def state(n, m, s):
if n > 2 or m > 3: return 'FAIL'
return "n%s_%s_%s" % (n, m, s)
def T(st, c):
n, m, s = st
if s == '':
return (n, m, c)
if s == '0':
return (n+1, m, '') if c=='0' else (n, m, c)
if s == '1':
return (n, m+1, '') if c=='1' else (n, m, c)
print 'digraph {'
for n in xrange(3):
for m in xrange(4):
for s in ['', '0', '1']:
for c in '01':
print ' %s -> %s [label="%s"]' % (state(n, m, s), state(*T((n, m, s), c)), c)
print '}'
答案 1 :(得分:2)
好吧,您可以使用单词来描述自动机,而不是绘制自动机。
我如何解决您的问题: 让顶点为三重
定义转换,启动状态和完成状态非常容易。
所以,有5 * 4 * 3 = 60个状态
你可能会注意到有一些不可实现的状态和某些状态可以联合到“失败的状态”,可以显着减少自动机的大小