Vì bạn muốn "chuyển đổi regex thành DFA trong vòng chưa đầy 30 phút", tôi cho rằng bạn đang làm việc bằng tay trên các ví dụ tương đối nhỏ.
Trong trường hợp này, bạn có thể sử dụng thuật toán của Brzozowski , tính toán trực tiếp máy tự động Nerode của ngôn ngữ (được biết là bằng với máy tự động xác định tối thiểu của nó). Nó dựa trên tính toán trực tiếp của các đạo hàm và nó cũng hoạt động cho các biểu thức chính quy mở rộng cho phép giao nhau và bổ sung. Hạn chế của thuật toán này là nó yêu cầu kiểm tra tính tương đương của các biểu thức được tính trên đường đi, một quá trình tốn kém. Nhưng trong thực tế, và cho các ví dụ nhỏ, nó rất hiệu quả.[1]
Chỉ tiêu còn lại . Hãy là một ngôn ngữ của A * và để u là một từ. Sau đó
u - 1 L = { v ∈ A * | u v ∈ L }
Ngôn ngữ u - 1 L được gọi là một thương trái (hoặc trái đạo hàm ) của L .LMột*bạn
bạn- 1L = { v ∈ A*∣ u v ∈ L }
bạn- 1LL
Máy tự động Nerode . Các automaton Nerode của là automaton xác định A ( L ) = ( Q , A , ⋅ , L , F ) nơi Q = { u - 1 L | u ∈ A * } , F = { u - 1 L | u ∈ L } và chức năng chuyển tiếp được xác định, đối với mỗi một ∈LMột( L ) = ( Q , A , ⋅ , L , F)Q = { u- 1L ∣ u ∈ A*}F= { u- 1L ∣ u ∈ L } , theo công thức
( u - 1 L ) ⋅ một = một - 1 ( u - 1 L ) = ( u một ) - 1 L
Cảnh giác với những nét khá trừu tượng này. Mỗi tiểu bang của A là một thương trái của L bằng một từ, và do đó là một ngôn ngữ của A * . Tình trạng ban đầu là ngôn ngữ L , và các thiết lập của tiểu bang cuối cùng là tập hợp của tất cả các thương số bên trái của L bằng một lời L .một ∈ A
( bạn- 1L ) ⋅ a = a- 1( bạn- 1L ) = ( u a )- 1L
MộtLMột*LLL
a , b
một- 11một- 1( L1∪ L2)một- 1( L1∩ L2)= 0= a- 1L1∪ u- 1L2,= a- 1L1∩ u- 1L2,một- 1bmột- 1( L1∖ L2)một- 1L*= { 10nếu a = bnếu 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]
Chỉnh sửa . (Ngày 5 tháng 4 năm 2015) Tôi mới phát hiện ra một câu hỏi tương tự: Thuật toán nào tồn tại để xây dựng một DFA nhận ra ngôn ngữ được mô tả bởi một biểu thức chính quy? đã được hỏi về cstheory. Câu trả lời một phần giải quyết các vấn đề phức tạp.
a(a|ab|ac)*a+
. Bạn có thể dịch trực tiếp điều đó sang NDFA mà bạn giảm xuống thành DFA hoặc bạn có thể bình thường hóa nó thành thứ gì đó ánh xạ ngay lập tức sang DFA.