Automaton cho khớp chuỗi con


7

Với như là một chuỗi trên một số bảng chữ cái, các thuật toán nổi tiếng nhất để tính toán một xác định automaton hữu hạn nhà nước tương ứng (DFA) chấp nhận bất kỳ chuỗi chứa là những gì ?ss

Tôi chủ yếu quan tâm đến độ phức tạp thời gian thấp nhất vì vậy nếu bạn cho tôi biết độ phức tạp được biết đến nhiều nhất trong ký hiệu O để xây dựng một máy tự động cho một chuỗi sẽ tốt như thế nào.

Câu trả lời:


7

Hendrik Jan đúng về thuật toán Knuth-Morris-Pratt (cảnh báo, wikipedia không giải thích điều đó đặc biệt tốt, một văn bản về thuật toán có lẽ là một lựa chọn tốt hơn). Hàm thất bại có thể được sử dụng để trích xuất một DFA có thể thực hiện khớp chuỗi. Không rõ ràng ngay lập tức rằng bảng thất bại là một DFA, nhưng với rất ít công việc, bảng chuyển đổi cho DFA có thể được xây dựng. Nếu là chuỗi mẫu bạn muốn khớp, thời gian để tạo bảng (và do đó xây dựng DFA) là .WO(|W|)

Ý tưởng trung tâm là bảng thất bại (Tôi sẽ cố gắng sử dụng cùng tên với wikipedia, chỉ để lấy ví dụ làm sẵn) cho bạn biết nơi bạn có thể tham gia vào chuỗi nếu trận đấu hiện tại không hoạt động ra ngoài, tức là nếu bạn không nhìn thấy nhân vật tiếp theo mà bạn mong đợi, có lẽ phần đầu của trận đấu bạn muốn đã được nhìn thấy, bạn chỉ bị nhầm về phía trước, vì vậy bạn chỉ muốn "theo dõi" một chút (lưu ý, không có quay lui thực sự theo nghĩa thuật toán thông thường).T

Vì vậy, không biết xấu hổ ăn cắp ví dụ từ wikipedia, nói rằng chúng ta có bảng thất bại :T

i0123456W[i]ABCDABDT[i]1000012

Chúng ta có thể xây dựng DFA như sau; chúng ta có các trạng thái , với đường trục chuyển tiếp khớp với toàn bộ mẫu. Để khớp với bảng, chúng ta sẽ gọi trạng thái bắt đầu và trạng thái cuối cùng (vì vậy trong ví dụ ). Xương sống sau đó là các chuyển đổi , vì vậy, trong ví dụ này, chúng ta đi từ trạng thái bắt đầu sang trạng thái trên một và từ để trên .|W|+1q1q|W|q6δ(qi1,W[i])=qiq1q0Aq2q3D

Bây giờ mẹo là thêm các chuyển đổi "ngược" chính xác để chúng ta không đi quá xa dọc theo xương sống khi chúng ta gặp phải điều gì đó sai. Đây là nơi chúng tôi chức năng thất bại. Nếu chúng ta ở trạng thái và chúng ta không xem là biểu tượng tiếp theo, thì chúng ta có thể chuyển sang nếu chúng ta thấy . Từ ví dụ, nếu chúng ta ở trạng thái và chúng ta không thấy , nhưng chúng ta thấy , chúng ta có thể đi đến . Mỗi biểu tượng khác đưa chúng ta trở về trạng thái bắt đầu.qi1W[i]qT[i]W[T[i]]q5DCq2

Lặp lại; có ba loại chuyển đổi, chuyển tiếp xương sống nếu mọi thứ đều ổn, quá trình chuyển đổi được đưa ra bởi bảng thất bại để chúng tôi có thể phục hồi một chút và chuyển tiếp khác đưa chúng ta trở lại trạng thái bắt đầu.|Σ|2

Tất nhiên, trạng thái bắt đầu và cuối cùng là một chút đặc biệt, trạng thái bắt đầu không thể quay lại xa hơn, vì vậy quá trình chuyển đổi phục hồi thất bại xuất hiện cùng với các chuyển đổi khác và khi chúng ta đạt đến trạng thái cuối cùng, chúng ta sẽ không gặp vấn đề gì nữa Vì vậy, nó là một trạng thái chìm quá.

Có một nếp nhăn cuối cùng, trường hợp biểu tượng thất bại giống như dự kiến ​​(ví dụ và ) trong trường hợp này, chúng ta có thể hoãn quyết định cho đến khi chúng khác nhau hoặc chúng ta có thể tạo NFA .W[1]W[5]

Ví dụ sau đó dẫn đến một DFA trông (lỗi sai) như:

DFA kết quả từ ví dụ bảng thất bại.

Các chuyển tiếp nét đứt thể hiện các chuyển tiếp "mọi thứ còn lại".

Thật dễ dàng để thấy rằng được đưa ra bảng, chúng ta có thể xây dựng DFA trong thời gian (trong một lần thực sự). Bảng cũng có thể được xây dựng trong thời gian - mã nguồn trên wikipedia là đủ. Nếu chúng ta thông minh, tất nhiên chúng ta có thể bỏ qua bước bảng trung gian và sử dụng thuật toán xây dựng bảng để tạo DFA ngay lập tức. Thời gian chạy này cũng là thời gian tốt nhất mà chúng ta có thể hy vọng, vì một DFA chỉ khớp với chuỗi này phải có ít nhấtchuyển tiếp (và trạng thái), vì vậy chúng ta cần đọc toàn bộ chuỗi , trong đó thực hiện các bước .O(|W|)O(|W|)|W||W|+1WΩ(|W|)


5

Câu trả lời. Mặc dù tôi đã thấy một câu trả lời bị xóa, tôi vẫn nghĩ rằng cấu trúc là tuyến tính theo chiều dài của chuỗi (xem xét kích thước bảng chữ cái không đổi). Aho Corasick 1975, đổi: 10.1145 / 360825.360855

Hoặc có lẽ là KMP. Aho & Corasick xem xét mô hình tự động khớp với mô hình cho một tập hợp các từ hữu hạn, tạo thành một cây với các con trỏ ngược trong trường hợp không khớp = thất bại. Đây là theo kiểu của thuật toán Knuth-Morris-Pratt, xem xét một chuỗi đơn. Tôi không thể tìm thấy dù KMP thực sự rõ ràng di chuyển từ automata trận đấu / sự thất bại đến automata xác định (với một sự chuyển tiếp cho tất cả các ký tự trong bảng chữ cái). Do đó, về cơ bản, cách tiếp cận KMP đủ cùng với một lập luận thông minh rằng điều này có thể được biến thành DFA trong thời gian tuyến tính. A & C đề cập rõ ràng bước cuối cùng đó. Tuy nhiên, bảng thất bại KMP đơn giản hơn một chút so với cấu trúc A & C (người ta không cần một chuỗi các chuỗi) và có thể được tìm thấy trên tất cả các trang web.

Một lưu ý. Bất cứ ai quan tâm đến việc khớp mẫu nên đọc bài báo KMP gốc, doi: 10.1137 / 0206024 , hoặc ít nhất là các nhận xét lịch sử từ Phần 7. Trích dẫn: "Knuth đã rất bối rối khi biết rằng Morris đã phát hiện ra thuật toán, mà không biết định lý Cook [. .] ". Bài báo KMP chỉ được xuất bản vào năm 1977 trong khi Morris đã triển khai phiên bản của mình trong một trình soạn thảo văn bản vào năm 1969, trong khi Knuth và Pratt phát hiện ra sau đó là một ứng dụng chứng minh Cook.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.