Da Sie "Regex in weniger als 30 Minuten in DFA konvertieren" möchten, arbeiten Sie vermutlich von Hand an relativ kleinen Beispielen.
In diesem Fall können Sie den Brzozowski-Algorithmus , der direkt den Nerode-Automaten einer Sprache berechnet (von dem bekannt ist, dass er dem minimalen deterministischen Automaten entspricht). Es basiert auf einer direkten Berechnung der Ableitungen und funktioniert auch für erweiterte reguläre Ausdrücke, die eine Schnittmenge und Ergänzung ermöglichen. Der Nachteil dieses Algorithmus besteht darin, dass die Äquivalenz der dabei berechneten Ausdrücke überprüft werden muss. Dies ist ein teurer Prozess. Aber in der Praxis und für kleine Beispiele ist es sehr effizient.[ 1 ]
Linke Quotienten . Sei eine Sprache von A ∗ und sei u ein Wort. Dann
u - 1 L = { v ∈ A * | u v ∈ L }
Die Sprache u - 1 L einen aufgerufen wird linken Quotient (oder links Derivat ) von L .LEIN∗u
u- 1L = { v ∈ A∗∣ u v ∈ L }
u- 1LL
Nerode-Automat . Der Nerode Automat von ist die deterministische Automat A ( L ) = ( Q , A , ⋅ , L , F ) , wobei Q = { u - 1 L | u ∈ A * } , F = { u - 1 L | u ∈ L } und die Übergangsfunktion wird für jedes a ∈ definiertLEIN( L ) = ( Q , A , ⋅ , L , F)Q = { u- 1L ∣ u ∈ A∗}F= { u- 1L ∣ u ∈ L } , nach der Formel
( u - 1 L ) ⋅ a = a - 1 ( u - 1 L ) = ( u a ) - 1 L
Hüten Sie sich vor dieser eher abstrakten Definition. Jeder Zustand von A ist ein linker Quotient von L durch ein Wort und daher eine Sprache von A ∗ . Der Ausgangszustand ist die Sprache L , und der Satz von Endzuständen ist die Menge aller linken Quotienten von L durch ein Wort von L .a ∈ A
( u- 1L ) ⋅ a = a- 1( u- 1L ) = ( u a )- 1L
EINLEIN∗LLL
a , b
ein- 11ein- 1( L1∪ L2)ein- 1( L1∩ L2)= 0= a- 1L1∪ u- 1L2,= a- 1L1∩ u- 1L2,ein- 1bein- 1( L1∖ L2)ein- 1L∗= { 10wenn a = bwenn a ≠ b= a- 1L1∖ u- 1L2,= ( a- 1L ) L∗
ein- 1( L1L2)= { ( a- 1L1) L2( a- 1L1) L2∪ a- 1L2si 1 ∉ L1,si 1 ∈ L1
L = ( a ( a b )∗)∗∪ ( b a )∗
1- 1Lein- 1L1b- 1L1ein- 1L2b- 1L2ein- 1L3b- 1L3ein- 1L4b- 1L4ein- 1L5b- 1L5= L = L1= ( a b )∗( a ( a b )∗)∗= L2= a ( b a )∗= L3= b ( a b )∗( a ( a b )∗)∗∪ ( a b )∗( a ( a b )∗)∗= b L2∪ L2= L4= ∅= ( b a )∗= L5= ∅= a- 1( b L2∪ L2) = a- 1L2= L4= b- 1( b L2∪ L2) = L2∪ b- 1L2= L2= ∅= a ( b a )∗= L3
[ 1 ]
Bearbeiten . (5. April 2015) Ich habe gerade eine ähnliche Frage entdeckt: Welche Algorithmen gibt es für die Erstellung eines DFA, der die von einem bestimmten Regex beschriebene Sprache erkennt? wurde auf cstheory gefragt. Die Antwort befasst sich teilweise mit Komplexitätsproblemen.
a(a|ab|ac)*a+
. Sie können dies entweder direkt in einen NDFA übersetzen, den Sie in einen DFA reduzieren, oder Sie können ihn auf etwas normalisieren, das sofort einem DFA zugeordnet wird.