Ponieważ chcesz „przekonwertować wyrażenie regularne na DFA w mniej niż 30 minut”, przypuszczam, że pracujesz ręcznie na stosunkowo małych przykładach.
W tym przypadku można zastosować algorytm Brzozowskiego , który bezpośrednio oblicza automat Nerode języka (o którym wiadomo, że jest równy minimalnemu automatowi deterministycznemu). Opiera się na bezpośrednim obliczeniu pochodnych, a także działa na rozszerzone wyrażenia regularne, umożliwiające przecięcie i uzupełnienie. Wadą tego algorytmu jest to, że wymaga sprawdzenia równoważności wyrażeń obliczanych po drodze, kosztownego procesu. Ale w praktyce i dla małych przykładów jest bardzo wydajny.[ 1 ]
Lewe ilorazy . Niech będzie językiem A * i niech u być słowo. Następnie
u - 1 L = { v ∈ * | u , v ∈ L }
Język u - 1 l nazywa się lewy iloraz (lub po pochodnej ) z L .L.ZA∗u
u- 1L = { v ∈ A∗∣ u v ∈ L }
u- 1L.L.
Automat Nerode . Automat Nerode z jest deterministyczny automat ( L ) = ( P , , ⋅ , L , F ) , gdzie P = { u - 1 l | u ∈ * } , M = { u - 1 l | u ∈ L } i funkcja przejścia jest zdefiniowana dla każdego a ∈L.ZA( L ) = ( Q , A , ⋅ , L , F)Q = { u- 1L ∣ u ∈ A∗}fa= { u- 1L ∣ u ∈ L } według wzoru
( u - 1 L ) ⋅ a = a - 1 ( u - 1 L ) = ( u a ) - 1 L
Strzeż się tej raczej abstrakcyjnej definicji. Każdy stan A jest lewym ilorazem L słowa, a zatem jest językiem A ∗ . Początkowy stan jest język L i zbiorem stanów końcowych jest zbiorem wszystkich pozostawionych ilorazów L przez słowo L .a∈A
(u−1L)⋅a=a−1(u−1L)=(ua)−1L
ALA∗LLL
a,b
a−11a−1(L1∪L2)a−1(L1∩L2)=0=a−1L1∪u−1L2,=a−1L1∩u−1L2,a−1ba−1(L1∖L2)a−1L∗={10if a=bif a≠b=a−1L1∖u−1L2,=(a−1L)L∗
a−1(L1L2)={(a−1L1)L2(a−1L1)L2∪a−1L2si 1∉L1,si 1∈L1
L=(a(ab)∗)∗∪(ba)∗
1−1La−1L1b−1L1a−1L2b−1L2a−1L3b−1L3a−1L4b−1L4a−1L5b−1L5=L=L1=(ab)∗(a(ab)∗)∗=L2=a(ba)∗=L3=b(ab)∗(a(ab)∗)∗∪(ab)∗(a(ab)∗)∗=bL2∪L2=L4=∅=(ba)∗=L5=∅=a−1(bL2∪L2)=a−1L2=L4=b−1(bL2∪L2)=L2∪b−1L2=L2=∅=a(ba)∗=L3
[1]
Edit . (5 kwietnia 2015 r.) Właśnie odkryłem, że podobne pytanie: jakie algorytmy istnieją do budowy DFA, który rozpoznaje język opisany przez dane wyrażenie regularne? został zapytany na cstheory. Odpowiedź częściowo rozwiązuje problemy ze złożonością.
a(a|ab|ac)*a+
. Możesz albo bezpośrednio przetłumaczyć to na NDFA, które redukujesz do DFA, albo możesz znormalizować to do czegoś, co mapuje natychmiast do DFA.