Đánh giá thuật toán: - Thuật toán Knuth-Morris-Pratt có chi phí về thời gian là Om+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... Ý tưởng: - Khác với KMP,
Trang 1Ví 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
Trang 2q=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
Trang 3q=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
Trang 4T=”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
Trang 5Đá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
Trang 6THU Ậ T TOÁN
BOYER-MOORE
Trang 7Ý 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 độ
Trang 8Thuậ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):
Trang 9Thuậ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++)
Trang 10Code:
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); } }