Un DFA est essentiellement définie par un transition table
. Ce tableau de transition cartes de chaque (valide) combinaison de l'état actuel et le courant entrée dans l'état successeur correspondant Une telle table peut être modélisée comme un dictionnaire de dictionnaires Par exemple: La dict externe contient les états comme clés et les dictionnaires comme valeurs, ces dictionnaires ont à leur tour les entrées valides comme clés et l'état successeur valeur
EDIT: L'exemple choisi n'est pas idéal, en ce sens qu'il a un alphabet assez grand (tous les caractères d'entrée possibles) d'au moins [a-zA-Z0-9]
, la réponse liée se limitait à [01]
pour une raison ;-) Jamais moins voici comment je commencerais:
{
# in state '' we have not yet processed/consumed any input
# it is the start state
# the only valid input is a 'w'
'': {'w': 'w'},
# in state 'w' we a have already consumed a 'w'
# the only valid input is another 'w'
'w': {'w': 'ww'},
# in state 'ww' we have previously consumed 'ww'
# the only valid input is still only a 'w'
'ww': {'w': 'www'},
# now the only valid input is a '.'
'www': {'.': 'www.'},
# this is where your example becomes unpractical:
# we have to add a transition for every valid input
# (you could get around this by using a defaultdict and some kind of special signal value, but im not quite sure you are up to that)
'www.': {'a': 'www.*', 'b': 'www.*', ...},
# I used the star in this state name to symbolize multiple (at least one) valid character
# we only leave this state if we encounter a '.'
'www.*': {'.': 'www.*.', 'a': 'www.*', 'b': 'www.*', ...},
# it should be obvious how to continue from here
'www.*.': ...
}
EDIT2: Mise en œuvre après le chat.
from collections import defaultdict
dfa = {
'initial': defaultdict(lambda: 'invalid', w='w'),
'w': defaultdict(lambda: 'invalid', w='ww'),
'ww': defaultdict(lambda: 'invalid', w='www'),
'www': defaultdict(lambda: 'invalid', [('.','www.')]),
'www.': defaultdict(lambda: 'www.*', [('.','invalid')]),
'www.*': defaultdict(lambda: 'www.*', [('.','www.*.')]),
'www.*.': defaultdict(lambda: 'www.*', [('c','www.*.c')]),
'www.*.c': defaultdict(lambda: 'www.*', [('o','www.*.co')]),
'www.*.co': defaultdict(lambda: 'www.*', [('m','www.*.com'), ('.','www.*.')]),
'www.*.com': defaultdict(lambda: 'www.*', [('.','www.*.')]),
'invalid': defaultdict(lambda: 'invalid')
}
def accepts(transitions,initial,accepting,s):
state = initial
for c in s:
state = transitions[state][c]
print(c, '->', state)
return state in accepting
print(accepts(dfa,'initial',{'www.*.com', 'www.*.co'},"www.hi.com"))
[Recherche Google pour "DFA en Python"] (https://encrypted.google.com/search?q=DFA+in+Python) fournit plusieurs exemples immédiatement (dont [un sur Stack Overflow] (http://stackoverflow.com/questions/35272592/how-are- finite-automata-implement-in-code)). Quel était le problème avec eux? –
Je comprends mieux le concept avec le débordement de pile que vous avez lié (je ne sais pas pourquoi je ne le trouvais pas auparavant), mais l'appliquer aux caractères sur ints me confond. – witcheR