Cho n chuỗi, một trong số chúng là một chuỗi con của một chuỗi khác?


9

Giả sử chúng ta được cung cấp một tập hợp gồm chuỗi, . Tôi muốn biết liệu bất kỳ chuỗi nào trong số đó là một chuỗi con của bất kỳ chuỗi nào khác trong bộ sưu tập. Nói cách khác, tôi muốn một thuật toán cho tác vụ sau:nS1,,Sn

Đầu vào:S1,,Sn

Đầu ra: sao cho là một chuỗi con của và hoặc Không có nếu không có như vậy tồn tạii,jSiSjiji,j

Có một thuật toán hiệu quả cho việc này?

Nếu chúng ta thay thế "chuỗi con" bằng "tiền tố", có một thuật toán hiệu quả (sắp xếp các chuỗi, sau đó thực hiện quét tuyến tính để so sánh các chuỗi liền kề; sắp xếp sẽ đảm bảo các chuỗi con liền kề). Nhưng có vẻ khó khăn hơn để kiểm tra xem bất kỳ chuỗi nào là một chuỗi con của bất kỳ chuỗi nào khác. Một thuật toán ngây thơ là lặp đi lặp lại trên tất cả các cặp , nhưng điều này đòi hỏi các bài kiểm tra chuỗi con . Có một thuật toán hiệu quả hơn?i,jΘ(n2)

Tôi đoán chúng ta có thể gọi đây là "thử nghiệm chuỗi con tất cả các cặp" hoặc đại loại như thế.

Mục tiêu cuối cùng của tôi là cắt tỉa bộ sưu tập để không có chuỗi nào là chuỗi con của bất kỳ chuỗi nào khác, bằng cách loại bỏ từng chuỗi là một chuỗi con của một thứ khác trong bộ sưu tập.


Gợi ý: mảng Suffix.
Bút danh

Là một lưu ý phụ, không chính xác nếu bạn loại bỏ các chuỗi con khi bạn tìm thấy chúng. Nó sẽ ít hơn. Ngoài ra, bạn nên sắp xếp theo độ dài vì một chuỗi dài hơn không thể xuất hiện trong một chuỗi ngắn hơn. Một lần nữa sai ở đây. Θ ( n 2 )Θ(n2)Θ(n2)
Alexis Wilke

@AlexisWilke, là chính xác: đó là số lần kiểm tra chuỗi con trong trường hợp xấu nhất (trường hợp xấu nhất là không có chuỗi nào là chuỗi con của bất kỳ chuỗi nào khác). Sắp xếp theo chiều dài chỉ cung cấp cho bạn một yếu tố hai, điều này không ảnh hưởng đến sự không triệu chứng. Θ(n2)
DW

Câu trả lời:


6

Bạn có thể xây dựng một cây hậu tố trong thời gian tuyến tính và kiểm tra xem có một nút bên trong tương ứng với một chuỗi đầy đủ (thời gian không đổi trên mỗi nút).

Chi tiết hơn, giả sử chúng ta được cung cấp các chuỗi .s1,,snΣ

  1. Xây dựng cây hậu tố (tổng quát) của với dấu đầu cuối phân biệt cặp đôi . n $ 1 , ... , $ nΣs1$1,s2$2,,sn$nn$1,,$nΣ

    Sử dụng thuật toán của Ukkonen , điều này có thể được thực hiện trong thời gian tuyến tính; tuyến tính trong tổng của tất cả các độ dài chuỗi.

  2. Giả sử rằng bạn gắn nhãn lá với nếu chúng đại diện cho hậu tố của , đi qua cây và tìm những lá có nhãn , tức là những lá tương ứng với đầy đủ dây.(i,j)si[j..|si|]sin(i,0)

    Điều này cần thời gian tuyến tính trong kích thước cây, mà chính nó là tuyến tính trong kích thước đầu vào.

  3. Lá hậu duệ của cha mẹ của (được chạm tới bởi một cạnh có nhãn ) đại diện cho tất cả các kết quả khớp từ tập hợp; điều này xuất phát từ sự bất biến cơ bản của cây hậu tố. Tìm bất kỳ một trận đấu nào bằng cách hạ xuống bất kỳ lá nào (nhưng(i,0)$i(i,0)

    Điều này một lần nữa mất thời gian tuyến tính.

Các dấu thiết bị đầu cuối riêng biệt là không thực sự cần thiết; một chuỗi duy nhất được sử dụng để chấm dứt tất cả các chuỗi là khá đủ miễn là bạn cho phép nhiều nhãn trên mỗi lá.

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.