0
Tải bản đầy đủ (.pdf) (76 trang)

Thuật toán KMP( Knuth Morris Pratt)

Một phần của tài liệu LUẬN VĂN:TÌM KIẾM MỜ VÀ ỨNG DỤNG TÌM KIẾM THÔNG TIN TRONG CÁC VĂN BẢN NÉN POTX (Trang 27 -31 )

Thuật toán KMP được trình bày chi tiết trong 4, 5, 14 nội dung như sau:

Duyệt từ trái sang phải trên S và P, mỗi lần một ký tự. Gọi con trỏ trên P là i, con trỏ trên S là j. Giả sử đã xuất hiện khúc đầu độ dài i - 1 của mẫu P và việc khớp mẫu thất bại tại vị trí j trên S, có nghĩa:

P1P2…Pi -1  Sj - i + 1Sj - i + 2…S j - 1 và Pi  Sj

Khi đó cần phải bắt đầu đối sánh mẫu từ vị trí j - h +1 trên S (trường hợp xấu nhất h = i - 1 trong thuật toán Brute - Force). Nếu tồn tại h > 0 sao cho h - 1 ký tự đầu của mẫu khớp với h - 1 ký tự cuối của đoạn S(j - 1) hay có nghĩa đã khớp với h - 1 ký tự cuối của P(i - 1) thì ta có thể bỏ

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn 19 h=next[i] S P P i j m m +1 j h=next[m+1] P S P qua h - 1 phép so sánh và tiếp tục so sánh 2 ký tự Ph và Sj (hình 1.1). Do h phụ thuộc vào i nên ký hiệu h = nexti, i = 1,…,m.

?

Hình 1.1. Ý nghĩa của mảng next

Nếu Sj  Ph thì phải tiếp tục lùi con trỏ trên mẫu. Để khắc phục nhược điểm do tình huống này gây ra, cần cố gắng tìm h sao cho Ph có nhiều khả năng bằng Sj. Vì Sj  Pi nên cần tìm h thoả mãn Ph Pi .

Trong KMP, khi i > m ta được một xuất hiện của mẫu bắt đầu từ vị trí j - m trên S. Để tìm xuất hiện tiếp theo, nếu bắt đầu đối sánh từ P1

và Sj thì có thể bỏ sót mẫu khi có mẫu xuất hiện lồng nhau. Vì vậy, khi con trỏ trên S dừng ở vị trí j, cần trượt mẫu đi một số vị trí sao cho h - 1 ký tự đầu của mẫu khớp với h - 1 ký tự cuối của S(j - 1) hay chính là khớp với h - 1 ký tự cuối của P(m). Do đó cần mở rộng mảng next với i = m + 1. (Hình 1.2).

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

20

Như vậy, với mỗi vị trí i trên P, i = 1..m + 1, cần xác định next i

thoả mãn:

+ nexti là số h lớn nhất sao cho h - 1 ký tự đầu của mẫu khớp với h - 1 ký tự cuối của P(i- 1).

+ Pi  Pnext i

(để có nextm + 1, tưởng tượng như đã bổ sung thêm ký tự  vào cuối P, với  là một ký tự không xuất hiện trong P).

Ví dụ 1.1. Với P = aababaab ta có bảng next như sau:

i 1 2 3 4 5 6 7 8 9

next[i] 0 0 2 0 2 0 0 2 4

Thuật toán 1.1. Xây dựng mảng next

procedure Initnext(); var i, j: Integer; begin i: = 1; j: = next

1

: = 0; while i< = m do begin

while j > 0 and Pi

P j do j: = next

j

; i: = i + 1; j: = j + 1;

if ( i < = m) and (Pi = P j) then next

i

:= next

j

else next

i

: = j;

end; end;

Thuật toán 1.2. KMP tìm nhiều lần lặp mẫu

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

21

Tìm mọi vị trí xuất hiện xâu mẫu P độ dài m trong xâu đích S độ dài n, đồng thời thống kê tần suất xuất hiện mẫu

var i, j: Integer; counter: Integer; begin Initnext (); i:= 1; j:= 1; counter: = 0; repeat while i < = m and j < = n do begin

while (i > 0) and (Sj

Pi) do i: = next

i

; i: = i + 1; j = j + 1;

end;

if( i > m) then begin

Ghi nhận vị trí xuất hiện mẫu là j - m; counter: =counter + 1; end; i: = next

m + 1

; until j > n; Ghi nhận counter; end;

Độ phức tạp của thuật toán 4, 5

- Pha tiền xử lý mẫu: Độ phức tạp thời gian và không gian để xây dựng bảng next là O(m).

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

22

Một phần của tài liệu LUẬN VĂN:TÌM KIẾM MỜ VÀ ỨNG DỤNG TÌM KIẾM THÔNG TIN TRONG CÁC VĂN BẢN NÉN POTX (Trang 27 -31 )

×