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à .WÔ ( | 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
iW[i]T[i]0A−11B02C03D04A05B16D2
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|+1q−1q|W|q6δ(qi−1,W[i])=qiq−1q0Aq2q3D
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.qi−1W[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ư:
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|)