Поскольку вы хотите «преобразовать регулярные выражения в DFA менее чем за 30 минут», я полагаю, вы работаете вручную над сравнительно небольшими примерами.
В этом случае вы можете использовать алгоритм Бжозовского , который вычисляет непосредственно автомат Нерода языка (который, как известно, равен его минимальному детерминированному автомату). Он основан на прямом вычислении производных, а также работает для расширенных регулярных выражений, допускающих пересечение и дополнение. Недостаток этого алгоритма состоит в том, что он требует проверки эквивалентности выражений, вычисленных по пути, дорогостоящего процесса. Но на практике и для небольших примеров это очень эффективно.[ 1 ]
Левые коэффициенты . Пусть язык A ∗, а u слово. Тогда
у - 1 л = { v ∈ * | U v ∈ L }
Язык у - 1 л называется левый фактор (или левой производной ) из L .LA*U
U- 1L = { v ∈ A*| U v ∈ L }
U- 1LL
Неродный автомат . Nerode автомат из является детерминированным автоматом ( L ) = ( Q , , ⋅ , L , F ) , где Q = { у - 1 л | у ∈ * } , Р = { у - 1 л | U ∈ L } и определена функция перехода для каждого a ∈LA( L ) = ( Q , A , ⋅ , L , F)Q = { и- 1L ∣ u ∈ A*}F= { ты- 1L ∣ u ∈ L } , по формуле
( u - 1 L ) ⋅ a = a - 1 ( u - 1 L ) = ( u a ) - 1 L
Остерегайтесь этого довольно абстрактного определения. Каждое состояние A является левым частным L по слову и, следовательно, является языком A ∗ . Начальное состояние языка L , и множество конечных состояний есть множество всех левых частных L по слову L .a ∈ A
( ты- 1L ) ⋅ a = a- 1( ты- 1L ) = ( у а )- 1L
ALA*LLL
а , б
a- 11a- 1( Л1∪ L2)a- 1( Л1∩ L2)= 0= а- 1L1∪ ты- 1L2,= а- 1L1∩ ты- 1L2,a- 1бa- 1( Л1∖ L2)a- 1L*= { 10если а = бесли a ≠ b= а- 1L1∖ у- 1L2,= ( а- 1L ) L*
a- 1( Л1L2)= { (- 1L1) L2( а- 1L1) L2∪ а- 1L2си 1 ∉ л1,si 1 ∈ L1
L = ( a ( a b )*)*∪ ( б а )*
1- 1La- 1L1б- 1L1a- 1L2б- 1L2a- 1L3б- 1L3a- 1L4б- 1L4a- 1L5б- 1L5= L = L1= ( а б )*( ( Б )*)*= L2= a ( b a )*= L3= b ( a b )*( ( Б )*)*∪ ( а б )*( ( Б )*)*= б л2∪ L2= L4= ∅= ( б а )*= L5= ∅= а- 1( б л2∪ L2) = а- 1L2= L4= б- 1( б л2∪ L2) = L2∪ б- 1L2= L2= ∅= a ( b a )*= L3
[ 1 ]
Редактировать . (5 апреля 2015 г.) Я только что обнаружил, что похожий вопрос: какие существуют алгоритмы для построения DFA, который распознает язык, описываемый данным регулярным выражением? был задан вопрос по истории. Ответ частично решает проблемы сложности.
a(a|ab|ac)*a+
. Вы можете либо напрямую перевести это в NDFA, который вы уменьшаете до DFA, либо вы можете нормализовать его к чему-то, что немедленно отображается в DFA.