Z-function: z-array và ứng dụng
Z-array[i] = độ dài tiền tố chung dài nhất của chuỗi với hậu tố bắt đầu tại i. Tính O(n) bằng z-box; ứng dụng matching và đếm lặp.
TL;DR: Z-function tính mảng z[i]: độ dài đoạn bắt đầu tại i trùng khớp với tiền tố của chuỗi. Thuật toán O(n) dùng z-box [l, r) (đoạn S[l..r-1] xa nhất bên phải đã biết là trùng với tiền tố) để tái dùng kết quả đã tính: nếu i nằm trong box hiện tại, lấy z[i-l] làm điểm khởi đầu thay vì so từ đầu. Ứng dụng nổi bật: ghép P + '#' + T rồi tìm vị trí z[i] = |P| để phát hiện mọi lần khớp trong O(n+m). Z-function và failure function của KMP là hai mặt của cùng một ý tưởng về tiền tố, và có thể chuyển đổi cho nhau.
Ở bài trước bạn thấy Rabin-Karp dùng rolling hash để bỏ qua so sánh ký tự. Bài này quay lại hướng "tận dụng tiền tố" như KMP, nhưng thay vì hỏi "hậu tố nào trùng tiền tố?" (lps), Z-function hỏi trực tiếp hơn: "đứng tại vị trí i, đoạn dài bao nhiêu bắt đầu từ đây trùng khớp với phần đầu chuỗi?"
1. Định nghĩa z-array
Hình dung bạn đặt phần đầu chuỗi lên như một cái thước rồi trượt dọc chuỗi: tại mỗi ô, thước khớp được bao nhiêu ký tự liên tiếp thì đó là z.
| Thước và tờ nháp | Z-function |
|---|---|
| Thước | Tiền tố của chuỗi |
| Số vạch trùng tại một ô | z[i] |
| Tờ nháp ghi đoạn đã biết là bản sao của thước | z-box [l, r) |
| Tra lại nháp thay vì đo lại | Dùng z[i-l] |
Cho chuỗi S độ dài n. Z-array là mảng z[0..n-1] với:
z[i]= độ dài của đoạn chung dài nhất giữaS(tính từ đầu) vàS[i..](hậu tố bắt đầu tạii).
Nói cách khác: z[i] là số ký tự lớn nhất sao cho S[0..z[i]-1] = S[i..i+z[i]-1].
Quy ước: z[0] thường bỏ qua hoặc đặt bằng 0 (tránh tầm thường, vì toàn bộ chuỗi luôn trùng chính nó).
Ví dụ S = "AABAAB" (tiền tố là "AAB..."):
| i | S[i..] | Trùng tiền tố bao nhiêu? | z[i] |
|---|---|---|---|
| 0 | AABAAB | (quy ước bỏ qua) | 0 |
| 1 | ABAAB | A (1: A=A, rồi B≠A) | 1 |
| 2 | BAAB | (không: B≠A) | 0 |
| 3 | AAB | AAB (3: AAB=AAB, hết hậu tố) | 3 |
| 4 | AB | A (1: A=A, rồi B≠A) | 1 |
| 5 | B | (không: B≠A) | 0 |
Vậy z = [0, 1, 0, 3, 1, 0].
Nhận xét trực giác: z[i] > 0 nghĩa là "có một đoạn bắt đầu tại i mà hình dạng giống hệt phần đầu chuỗi", và đó là gợi ý để tìm pattern matching.
All-Access Pass
Phần còn lại của bài dành cho All-Access Pass
Bạn vừa đọc phần xem trước. Hai bài đầu của mỗi khoá luôn đọc trọn miễn phí.
- Đọc trọn mọi bài trong 6 khoá System Design và dữ liệu phân tán
- AI Mentor trả lời theo toàn bộ nội dung bài
- Trả một lần, không tự gia hạn, không tự trừ tiền
Trọn đời
1.690.000 ₫
Trả một lần, dùng mãi mãi
Gói năm
699.000 ₫
365 ngày · ≈ 58.000 ₫/tháng
Thanh toán bằng thẻ Visa/Master/JCB qua Polar. Xem bảng giá
Bài này có giúp bạn hiểu bản chất không?
Bài này đáng gửi cho bạn học cùng?
Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.
Thảo luận & góp ý
Hỏi đáp về bài này