Thuật toán KnuthTHER MorrisTHER Pratt (KMP)

Tram Ho

Chuỗi, không nghi ngờ gì, là một phần không biết gì trong lập trình. Nó là một yếu tố hấp dẫn trong thế giới khoa học máy tính này. Tìm kiếm một chuỗi xác định hoặc chuỗi chứa đầy đủ là một trong những công việc cháy bỏng trong công việc liên quan đến khoa học máy tính. Thuật toán KnuthTHER MorrisTHER Pratt, trong thuật toán KMP ngắn là thuật toán tuyến tính sẽ được mở rộng trong bài viết này.

Lý lịch

Hãy nghĩ về một kịch bản – Chúng ta có một Chuỗi S = "I become so numb" và chúng ta cần tìm kiếm một chuỗi khác A = "numb" trong S. Cách tiếp cận đầu tiên để thực hiện nhiệm vụ này là gì? Đơn giản nhất sẽ là – bắt đầu từ chỉ số 0 của chuỗi S để tìm ký tự đầu tiên của A. Nếu nó khớp thì kiểm tra các ký tự tiếp theo của A trong S. Giải pháp trong ruby ​​sẽ như thế nào –

Nếu bạn quan sát mã, bạn có thể thấy rằng độ phức tạp của giải pháp này là O (mn) trong đó m = chiều dài của s và n = chiều dài của a. Nó ổn nếu cả s và a có kích thước nhỏ. Hãy nghĩ về thực tế rằng chúng là rất lớn; những gì đến trong tâm trí của bạn. Chắc chắn hệ thống sẽ đứng yên. Trong suy nghĩ cẩn thận, chúng tôi trở nên ngạc nhiên khi biết rằng chúng tôi có thể tra cứu bất kỳ chuỗi nào trong trình đọc PDF hoặc notepad hoặc thăng hoa trong thời gian không đáng kể, bất kể nội dung được mở lớn như thế nào (có thể là 1000 trang sách). Tối thiểu một ngày sẽ là cần thiết nếu chúng ta đi trên con đường đó. Để tìm một giải pháp hiệu quả về thời gian, chúng tôi sẽ khám phá thuật toán KMP.

Thuật toán Knuth

vào năm 1977, Donald Knuth, Vaughan Pratt và James H. Morris đã xuất bản một thuật toán tìm kiếm chuỗi được gọi là thuật toán KMP. Trong giải pháp trước đây, chúng tôi đã nâng cao bằng cách so sánh từng chữ cái của một chuỗi. nhưng trong thuật toán KMP, nó đã cố gắng bỏ qua một số chữ cái – đó là ý tưởng cơ bản

Các bước thuật toán như sau

  • Đầu tiên chúng ta cần tạo một bảng Pi theo chuỗi patter P.
  • Sau đó, chúng tôi sẽ kiểm tra các mẫu bằng sự trợ giúp của bảng Pi
  • Nếu bất kỳ ký tự nào không khớp, chúng ta có thể bỏ qua một số ký tự dựa trên bảng pi

Bảng Pi

Bảng này là mảng trợ giúp cho thuật toán KMP. Kích thước của bảng này sẽ là kích thước của chuỗi mẫu P. Mỗi phần tử của mảng này sẽ lưu trữ tiền tố hoặc hậu tố dài nhất phù hợp của chuỗi P.

alt

Nếu bạn nhìn vào hình trên – đối với chỉ mục đầu tiên của P thì hậu tố và tiền tố trống nên chúng ta đặt 0 trong chỉ mục đó.

  • Chúng tôi cũng sẽ làm tương tự cho chỉ số thứ hai.
  • Đối với phần tử thứ ba của P, hậu tố = tiền tố = 1. Vì vậy, chúng tôi đặt 1
  • Đối với phần tử thứ tư của P, hậu tố = tiền tố = "ab" = 2. Vì vậy, chúng tôi đặt 2 và cứ thế

Nếu chúng ta làm điều đó trên mã

Tìm mẫu bằng bảng Pi

Bây giờ chúng ta cần tìm chuỗi mẫu P trong chuỗi tham chiếu S. Bạn có thể xem hình dưới đây alt

Tìm một mẫu trong chuỗi S bằng cách sử dụng bảng pi cũng giống như tạo bảng pi ở trên. Nếu chúng tôi nhận được bất kỳ sự khác biệt nào trong S và P, chúng tôi có thể nhảy một số ký tự trong S với sự trợ giúp của bảng pi vì chúng tôi đã cân bằng hậu tố và tiền tố. Nếu chúng ta viết mã này bằng ruby, chúng ta có thể viết như thế này –

Phức tạp

Đối với tính toán bảng pi, vòng lặp for được lặp lại m-1 lần trong đó m = kích thước của chuỗi mẫu P. Độ phức tạp của phần đó là O(m) . Và trong phần khớp KMP, vòng lặp chạy n lần trong đó n = kích thước của văn bản S. Vì vậy, độ phức tạp thời gian cho phần khớp là O(n) . và thuật toán KMP chạy theo độ phức tạp thời gian O(m+n) , có thể chấp nhận hơn so với tính toán O (mn) của lực lượng vũ phu. Độ phức tạp không gian của thuật toán này là O(m) .

Tôi muốn các gyst từ bài đăng này sẽ làm cho bạn quan tâm để biết thêm về các thuật toán tìm kiếm. Chúc mừng mã hóa !!

Tín dụng Pic: Blog của Tanvir

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo