Please purchase a Please purchase a personal license. personal license. THU THU Ậ Ậ T TO T TO Á Á N KNUTT N KNUTT - - MORRIS MORRIS - - PRATT PRATT String matching String matching Bài toán: - Tìm vị trí xuất hiện đầu tiên của chuỗi con trong 1 đoạn text - Tìm vị trí xuất hiện tiếp theo bằng cách thay đổi giá trị đầu của đoạn text - Thuật toán thông thường: - So sánh kí t ự đầ u c ủ a đ o ạ n text và kí t ự đầ u c ủ a chu ỗ i con - N ế u trùng so sánh kí t ự ti ế p theo - N ế u khác so sánh t ă ng kí t ự ở đoạ n text - Quá trình ti ế p di ễ n cho đế n khi h ế t chu ỗ i con String matching String matching Thuật toán: isub= 0; itext = 0; //ví tr ị hi ệ n t ạ i c ủ a chu ỗ i và đoạ n text starttext=0; //v ị trí b ắ t đầ u while (itext <= strlen(text) && isub<=strlen(sub) { if (text[itext]==sub[isub) { itext++; isub++; } else { startext++; itext=startext; isub=0;} } if (isub > strlen(sub) return textstart; // tìm th ấ y else return 0; //không tìm th ấ y String matching String matching Đánh giá thuật toán: - m – strlength của substring - n - strlength của đoạn text Số lần so sánh trong trường hợp xấu nhất: m*(t-m+1) Ví dụ: substring (AA….AAB), text(AA…AAA) Substring có m-1 A, text có n A Dẫn đến trường hợp xấu nhất Knuth Knuth - - Morris Morris - - Pratt Pratt Ý tưởng: – Để dễ mô tả,ta coi các xâu đánh số từ 1. – Xâu W gọi là tiền tố(prefix) của xâu X nếu X có dạng WY (Y là 1 xâu nào đó) – VD: X=“qetyughjk” W=“qety” – Xâu W gọi là hậu tố(suffix) của xâu X nếu X có dạng YW (Y là 1 xâu nào đó) – VD: X=”qetyughjk” W=”yughjk” – Nếu có thêm W# X thì W gọi là prefix(hay suffic) thực sự của X. Knuth Knuth - - Morris Morris - - Pratt Pratt Ý tưởng: – Hàm int Prefix(int q): trả độ dài của prefix dài nhất của P[1 m] đồng thời là suffix thực sự của P[1 q]. VD: P=“abcabcd” Prefix(1)=0 P=“abcabcd” Prefix(2)=0 P=“abcabcd” Prefix(3)=0 P=“abcabcd” Prefix(4)=1 P=“abcabcd” Prefix(5)=2 P=“abcabcd” Prefix(6)=3 P=“abcabcd” Prefix(7)=0 Knuth Knuth - - Morris Morris - - Pratt Pratt Ví dụ: 1. P=”abc abc” Prefix(6)=3. 2. P=”abcababcabc” Prefix(11)=3 3. P=”abcabcabcaa” Prefix(11)=1 4. P=”abcababcabd” Prefix(11)=0 Knuth Knuth - - Morris Morris - - Pratt Pratt Thuật toán tính Prefix: PI [1]= 0 ; k=0; for (q=2;q<=m;q++) { while (k>0 && P[k+1] <>P[q]) k=PI[k]; if(P[k+1]==P[q]) k++; PI[q]=k; } Knuth Knuth - - Morris Morris - - Pratt Pratt Thuật toán tính KMP: – Xác định độ dài q của xâu vừa là prefix của P,vừa là suffix của T[1 i] với i = 1->n. – Nếu q=m thì vị trí khớp chính là i-m+1. Cách tính q gần như cách tính Prefix. q=0 for (i=1;i<=n;i++) { while (q>0 && P[q+1]<>T[i]) q=PI[q]; if (P[q+1]==T[i]) q++; if (q==m) {printf(“%d”, i-m+1);q=PI[q]} } . hiện tiếp theo bằng cách thay đổi giá trị đầu của đoạn text - Thuật toán thông thường: - So sánh kí t ự đầ u c ủ a đ o ạ n text và kí t ự đầ u c ủ a chu ỗ i con - N ế u trùng so sánh kí. đế n khi h ế t chu ỗ i con String matching String matching Thuật toán: isub= 0; itext = 0; //ví tr ị hi ệ n t ạ i c ủ a chu ỗ i và đoạ n text starttext=0; //v ị trí b ắ t đầ u while (itext. textstart; // tìm th ấ y else return 0; //không tìm th ấ y String matching String matching Đánh giá thuật toán: - m – strlength của substring - n - strlength của đoạn text Số lần so sánh trong trường