Rabin-Karp: rolling hash cho đa mẫu
So khớp bằng hash: tính hash cửa sổ trượt trong O(1) nhờ rolling hash. Mạnh khi tìm nhiều pattern cùng lúc; rủi ro hash collision.
TL;DR: Rabin-Karp thay việc so từng ký tự bằng so hash của cửa sổ trượt. Rolling hash cập nhật trong O(1) khi trượt một ký tự: bỏ ký tự trái, thêm ký tự phải. Khi hash khớp, mới so ký tự để xác nhận (tránh "spurious hit", hash trùng nhưng chuỗi khác). Trung bình O(n+m); worst-case O(n·m) khi nhiều collision. Ưu thế lớn nhất: tìm k pattern cùng độ dài chỉ cần một lần quét text, hash k pattern vào Set, mỗi cửa sổ kiểm tra O(1) thay vì O(k·m).
KMP ở bài trước luôn O(n+m) vì không lùi con trỏ text. Rabin-Karp đổi chỗ so: nếu hash của cửa sổ khác hash của pattern thì bỏ qua cửa sổ đó mà không so ký tự nào. Nếu hash bằng nhau, xác suất cao là khớp thật, chỉ cần verify lại.
1. Ý tưởng: so hash thay vì so ký tự
Giả sử ta có hàm hash(s) trả về một số nguyên dương cho mỗi chuỗi s. Khi trượt cửa sổ dài m qua text:
- Tính
hp = hash(P), hash của pattern, tính một lần. - Tính
hw = hash(T[0..m-1]), hash của cửa sổ đầu tiên. - Với mỗi bước trượt: nếu
hw ≠ hp→ bỏ qua (không so ký tự). Nếuhw = hp→ so ký tự để xác nhận. - Cập nhật
hwcho cửa sổ kế tiếp, đây là chỗ rolling hash phát huy.
Vấn đề: nếu mỗi bước tính lại hash(T[i..i+m-1]) từ đầu thì mất O(m), tổng O(n·m), không khác gì naive. Cần cập nhật hash trong O(1) khi trượt 1 ký tự.
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