Knuth
Knuth
-
-
Morris
Morris
-
-
Pratt
Pratt
Ví dụ:
T=”abcabcabcaababcba” P=”abcabca”
P=”abcabca” PI[1]=0
P=”abcabca” PI[2]=0
P=”abcabca” PI[3]=0
P=”abcabca” PI[4]=1
P=”abcabca” PI[5]=2
P=”abcabca” PI[6]=3
P=”abcabca” PI[7]=4
Knuth
Knuth
-
-
Morris
Morris
-
-
Pratt
Pratt
q=0; T=”abcabcabcaababcba” P=”abcabca”
• i=1: P[0+1]=T[1] q++ q=1
• i=2: P[1+1]=T[2] q++ q=2
• i=3: P[2+1]=T[3] q++ q=3
• i=4: P[3+1]=T[4] q++ q=4
• i=5: P[4+1]=T[5] q++ q=5
• i=6: P[5+1]=T[6] q++ q=6
• i=7: P[6+1]=T[7] q++ q=7 Xuất s=1
Knuth
Knuth
-
-
Morris
Morris
-
-
Pratt
Pratt
q=PI[7]= 4 P=”abcabca” T=”abcabcabcaababcba
• i=8: P[4+1]=T[8] q++ q=5
• i=9: P[5+1]=T[9] q++ q=6
• i=10:P[6+1]=T[10] q++ q=7 Xuất s=4
q=PI[7]= 4 P=”abcabca” T=”abcabcabcaababcba
• i=11: P[4+1]<>T[11] q=PI[4]=1 P=”abcabca”
P[1+1]<>T[11] q=PI[1]=0 P=”abcabca”
P[0+1]=T[11] q=0+1=1
Knuth
Knuth
-
-
Morris
Morris
-
-
Pratt
Pratt
T=”abcabcabcaababcba P=”abcabca
• i=12:P[1+1]=T[12] q=1+1=2
• i=13:P[2+1]<>T[13] q=PI[2]=0
P[0+1]=T[13] q=0+1=1
P=”abcabca” T=”abcabcabcaababcba
• i=14: P[1+1]=T[14] q=1+1=2
• i=15: P[2+1]=T[15] q=2+1=3
• i=16: P[3+1]<>T[16] q=PI[3]=0
P[0+1]<>T[16] q=0
• i=17: P[0+1]=T[17] -> q=0+1=1
Knuth
Knuth
-
-
Morris
Morris
-
-
Pratt
Pratt
Đánh giá thuật toán:
- Thuật toán Knuth-Morris-Pratt có chi phí về thời
gian là O(m+n) với nhiều nhất là 2n-1 lần số lần so
sánh ký tự trong quá trình tìm kiếm.
THU
THU
Ậ
Ậ
T TO
T TO
Á
Á
N BOYER
N BOYER
-
-
MOORE
MOORE
Boyer
Boyer
-
-
Moore
Moore
Ý tưởng:
- Khác với KMP, thuật toán Boyer-Moore kiểm tra
các ký tự mẫu từ phải sang trái
- Hàm int Last(char c, char*P): Trả về vị trí cuối
cùng của c trong mẫu P. Nếu c không xuất hiện
trọng P thì trả về -1
– Ví dụ: P= ”abcabdacgj”
Last(‘a’,P)=6; Last(‘d’,P)=5; Last(‘p’,P)=-1
– Dựa trên cơ sở hàm Last, ta sẽ xây dựng các bước
nhảy để tăng tính tốc độ
Boyer
Boyer
-
-
Moore
Moore
Thuật toán:
– Gọi s là vị trí cần khảo sát. Ban đầu s=0.
– Lặp chừng nào s<=n-m:
• So sánh 2 xâu P và T, l
ầ
n l
ượ
t t
ừ
v
ị
trí cu
ố
i cùng, cho
t
ớ
i khi g
ặ
p các kí t
ự
khác nhau. G
ọ
i
đ
ó là kí t
ự
th
ứ
j
trong xâu P, t
ươ
ng
ứ
ng v
ị
trí s+j trong T
– Nếu j=-1 => Đây là vị trí khớp, xuất s. Sau đó dịch
phải bình thường(s++)
– Trái lại, gọi c=T[s+j]. Xét Last(c,P):
Boyer
Boyer
-
-
Moore
Moore
Thuật toán:
• TH1: Last(c,P)<j. Ta d
ị
ch P
để
v
ị
trí Last[c,P] trùng v
ớ
i
v
ị
trí s+j c
ủ
a xâu T. D
ễ
th
ấ
y thao tác d
ị
ch là s=s+j-
last(c,P)
• TH2: Last(c,P)=-1. Kí t
ự
c không xu
ấ
t hi
ệ
n trong P.
D
ị
ch toàn b
ộ
P ra sau v
ị
trí s+j c
ủ
a T. D
ễ
th
ấ
y thao tác
d
ị
ch v
ẫ
n làs=s+j- last(c,P).
• TH3: N
ế
u Last(c,P)>j. Ta ch
ỉ
d
ị
ch ph
ả
i 1 v
ị
trí (s++)
Boyer
Boyer
-
-
Moore
Moore
Code:
s=0;
while (s<=n-m)
{ j= m-1;
while ((j>=0)&&(T[j+s]==P[j])) j ;
if (j==-1)
{ printf(“%d”,s); s++; }
else { k=last(T[j+s],P); s=s+ max( j-k,1); }
}