Mảng hậu tố có thể được sử dụng cho vấn đề này. Chúng chứa các vị trí bắt đầu của mỗi hậu tố của chuỗi được sắp xếp theo thứ tự từ điển. Mặc dù chúng có thể được xây dựng một cách ngây thơ trong phức tạp, có những phương pháp để xây dựng chúng trong Θ ( n ) phức tạp. Xem ví dụ này và này . Hãy để chúng tôi gọi mảng hậu tố SA.O ( n logn )Θ ( n )
Khi mảng hậu tố đã được xây dựng, chúng ta cần xây dựng mảng Tiền tố chung dài nhất (LCP) cho mảng hậu tố. Mảng LCP lưu trữ độ dài của tiền tố chung dài nhất giữa hai tiền tố liên tiếp trong mảng hậu tố (hậu tố từ vựng liên tiếp). Do đó, LCP [i] chứa độ dài của tiền tố phổ biến dài nhất giữa SA [i] và SA [i + 1]. Mảng này cũng có thể được xây dựng trong thời gian tuyến tính: xem ở đây , ở đây và ở đây để biết một số tài liệu tham khảo tốt.
Bây giờ, để tính độ dài của tiền tố dài nhất phổ biến cho bất kỳ hai hậu tố nào trong cây hậu tố (thay vì các hậu tố liên tiếp), chúng ta cần sử dụng một số cấu trúc dữ liệu của RMQ . Nó đã được hiển thị trong các tham chiếu ở trên (và có thể dễ dàng nhìn thấy nếu mảng được hiển thị dưới dạng cây hậu tố), rằng độ dài của tiền tố chung dài nhất giữa hai hậu tố có vị trí và v ( u < v ) trong mảng hậu tố , có thể thu được là m i n u < = k < = v - 1 L C P [ k ]bạnvbạn < vm i nu < = k < = v - 1L CP[ k ]. Một RMQ tốt có thể xử lý trước mảng trong thời gian O ( n ) hoặc O ( n log n ) và trả lời các truy vấn có dạng L C P [ u , v ] trong thời gian O ( 1 ) . Xem ở đây để biết thuật toán RMQ succint và ở đây để có hướng dẫn tốt về RMQ, và mối quan hệ (và mức giảm) giữa LCA và RMQ. Điều này có một cách tiếp cận thay thế tốt đẹp.L CPÔ ( n )O ( n logn )L CP[ u , v ]Ô ( 1 )
Với thông tin này, chúng tôi xây dựng mảng hậu tố và các mảng liên quan (như được mô tả ở trên) để nối hai chuỗi với một dấu phân cách ở giữa (chẳng hạn như T # P, trong đó '#' không xảy ra trong một trong hai chuỗi). Sau đó, chúng ta có thể thực hiện khớp chuỗi k không khớp bằng phương pháp "kangaroo". Điều này và điều này giải thích phương pháp kangaroo trong bối cảnh của cây hậu tố, nhưng cũng có thể được áp dụng trực tiếp cho mảng hậu tố. Với mọi chỉ số của văn bản T , hãy tìm L C P của hậu tố T bắt đầu từ i và hậu tố của PTôiTLCPTiPbắt đầu từ 0. Điều này cho biết vị trí sau đó xảy ra sự không khớp đầu tiên khi khớp với T [ i ] . Đặt độ dài này là l 0 . Bỏ qua ký tự không khớp trong cả T và P và cố gắng khớp các chuỗi còn lại. Nghĩa là, một lần nữa tìm L C P của T [ i + l 0 + 1 ] và P [ l 0 + 1 ] . Lặp lại điều này cho đến khi bạn có được k không khớp hoặc kết thúc chuỗi. MỗiPT[i]l0TPLCPT[i+l0+1]P[l0+1]k là O ( 1 ) . Có O ( k ) L C P 'cho mỗi chỉ số i của T , tạo ra tổng độ phức tạp của O ( n k ) .LCPO(1)O(k) LCPiTO(nk)
Tôi đã sử dụng một cách dễ dàng hơn để thực hiện RMQ với tổng độ phức tạp của log hoặc O ( n k + n log n ) nếu m = O ( n ) , nhưng nó có thể được thực hiện trong O ( n k ) như mô tả ở trên. Có thể có các phương pháp trực tiếp khác cho vấn đề này, nhưng đây là một cách tiếp cận mạnh mẽ và chung chung có thể được áp dụng cho rất nhiều vấn đề tương tự.O(nk+(n+m)log(n+m))O(nk+nlogn)m=O(n)O(nk)