finite-automata – 设计DFA(字母’a’和’b’):字符串中’a’的数量必须是3的倍数,字符串不包含’aba’

这是问题所在:

《finite-automata – 设计DFA(字母’a’和’b’):字符串中’a’的数量必须是3的倍数,字符串不包含’aba’》

当我第一次遇到它时,这是我的推理路线:

>这个似乎很难
>为它找到正则表达式似乎很棘手,所以我不能按照这条路径将正则表达式转换为DFA
>所以我决定解决问题的第一部分:接受一个字符串,其数字’a’是3的倍数.这很简单,你只需要3个状态:1,2,3和1作为开始状态,如果有一个输入’a’,你会转到下一个,如果它’b’你保持在那个状态,并且开始状态也是完成状态.但在这个练习中,这3个州实际上是3个“大”州.然后问题就变成了设计这些“大国”的内部以及它们如何相互作用.

我别无选择,只能使用猜测来达成解决方案.这是我想出的结果(1,2,3是完成状态,3是开始状态,如果收到输入’a’,7和9都变为1):
《finite-automata – 设计DFA(字母’a’和’b’):字符串中’a’的数量必须是3的倍数,字符串不包含’aba’》
我还在这个上使用了DFA最小化,并发现它已经很小了.但是,教科书提供了另一种解决方案:
《finite-automata – 设计DFA(字母’a’和’b’):字符串中’a’的数量必须是3的倍数,字符串不包含’aba’》

但我不明白它是如何正确的!我只是想不出来:(.我甚至不知道我的解决方案是否100%正确.请帮助我,非常感谢:)

最佳答案 你的答案似乎是正确的.我没有仔细证明它,但逻辑相当清楚.此外,我写了一个Python程序来测试它:

def accepts(transitions,initial,accepting,s):
    state = initial
    for c in s:
        state = transitions[state][c]
    return state in accepting

dfa = {1:{'a':4, 'b':2},
       2:{'a':10, 'b':3},
       3:{'a':4, 'b':3},
       4:{'a':7, 'b':5},
       5:{'a':10, 'b':6},
       6:{'a':7, 'b':6},
       7:{'a':1, 'b':8},
       8:{'a':10, 'b':9},
       9:{'a':1, 'b':9},
       10:{'a':10, 'b':10}}

def dfaTest(s):
    return accepts(dfa,3,{1,2,3},s)

def valid(s):
    return s.count('a') % 3 == 0 and not 'aba' in s

import random

tests = [''.join(random.choice(['a','b']) for j in range(100)) for i in range(1,1001)]

print(all(valid(s) == dfaTest(s) for s in tests))

函数接受的操作在this answer中解释.我根据您的图表对其进行了定制.为了对其进行压力测试,我生成了100,000个随机输入,其长度范围为1到1000,然后将DFA的输出与条件的直接验证进行比较.每次运行此代码时,输​​出都是令人满意的True.

要测试单个字符串:

>>> dfaTest('ababba')
False
>>> dfaTest('abbabba')
True
点赞