Phần 1: Các thuật toán tìm kiếm mẫu từ bên trái qua bên phải1.1 Thuật toán Morris- Pratt Thuật toán a.. • Thực hiện từ trái sang phải.• Có pha tiền xử lý với độ phức tạp Om.. • Độ phức
Trang 1KHOA CÔNG NGHỆ THÔNG TIN
BÁO CÁO CHUYÊN ĐỀ CÁC THUẬT TOÁN ĐỐI SÁNH MẪU PATTERN MATCHING ALGORITHMS
Giảng viên : Nguyễn Duy Phương
Sinh viên : Trần Thị Hoài
Hà Nội, tháng 6 năm 2016
Trang 2MỤC LỤC
Trang 3Phần 1: Các thuật toán tìm kiếm mẫu từ bên trái qua bên phải
1.1 Thuật toán Morris- Pratt
Thuật toán
a Đặc điểm
• Thực hiện từ trái sang phải
• Có pha tiền xử lý với độ phức tạp O(m)
• Độ phức tạp thuật toán là O(n + m);
• mảng mpNext chứa độ dài trùng nhau giữa tiền tố và hậu tố của xâu
Formats: preMp(char *x, int m, int mpNext[])
Actions:
void preMp(char *x, int m, int mpNext[]) {
i = 0; //mang mpNext the hien do dai trung nhau lon
j = mpNext[0] = -1; //nhat giua tien to va hau to
while (i < m) {
while (j > -1 && x[i] != x[j])
{
j = mpNext[j]; //chay nguoc xet xem do dai lon nhat cua
//vi tri giong voi x[i]
Kiểm nghiệm preMp :
Xâu vào ATCACATCATCA
Trang 4C 4 1
0 -1
• Xâu mẫu X =(x0, x1, ,xm), độ dài m
• Văn bản Y =(y0, y1, ,xn), độ dài n.Output:
Trang 5• Thực hiện từ trái sang phải.
• Có pha tiền xử lý với độ phức tạp O(m)
• Độ phức tạp thuật toán là O(n + m);
b.Thuật toán
Thuật toán PreKmp: //thực hiện bước tiền xử lý xác định số ký tự có tiền tố và hậu tố trùng nhau
Input :
Trang 6• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
Output: Mảng giá trị kmpNext[].
if ( len != 0 ) { len = kmpNext[len-1]; } else { kmpNext[i] = 0; i++; }
Kết luận: kmpNext[] = {0, 0, 1, 2, 0, 1, 2, 3, 4}.
Trang 7Thuật toán Knuth-Morris-Partt:
Input :
• Xâu mẫu X =(x0, x1, ,xm), độ dài m
• Văn bản Y =(y0, y1, ,xn), độ dài n
(X[0]==Y[0]): Yes No i=1, j=1
(X[1]==Y[1]): Yes No i=2, j=2
(X[2]==Y[2]): Yes No i=3, j=3
(X[3]==Y[3]): Yes No i=4, j=2
(X[2]==Y[4]): No No i=4, j=0
Trang 8(X[0]==Y[4]): No No i=5, j=0
(X[0]==Y[5]): Yes No i=6, j=1
(X[1]==Y[6]): Yes No i=7, j=2
(X[2]==Y[7]): Yes No i=7, j=2
(X[1]==Y[8]): No No i=7, j=2
(X[0]==Y[8]): No No i=7, j=2
(X[0]==Y[9]): No No i=7, j=2
(X[0]==Y[10]): Yes No i=7, j=2
(X[1]==Y[11]): Yes No i=7, j=2
(X[2]==Y[12]): Yes No i=7, j=2
(X[3]==Y[13]): Yes No i=7, j=2
(X[4]==Y[14]): Yes No i=7, j=2
(X[5]==Y[15]): Yes No i=7, j=2
(X[6]==Y[16]): Yes No i=7, j=2
(X[7]==Y[17]): Yes No i=7, j=2
(X[8]==Y[18]): Yes Yes i=19, j=4
1.3 Thuật toán Karp-Rabin
a.Đặc điểm
● Thực hiện từ trái qua phải
● Sử dụng một hàm hash
● Độ phức tạp của pha tiền sử lý là O(m)
● Độ phức tạp của pha tìm kiếm là O(m x n)
● Thời gian chạy mong muốn là O(m + n)
b.Thuật toán
Trang 9Thuật toán Karp- Rabin :
Input :
• Xâu mẫu pat độ dài M
• Văn bản nguồn txt độ dài N
if(hx == hy && check(pat,txt, j)) //đồng thời trùng giá trị hash và check lại 1 lần nữa
System.out.println("vi tri trung nhau "+j);
Trang 10● Đây là thuật toán xử lý bit
● Có hiệu quả khi độ dài mẫu nhỏ hơn giới hạn vật lý
● Pha tiền xử lý độ phức tạp không gian và thời gian là O(m + ⌠)
● Pha tìm kiếm độ phức tạp là O(n)
b.Thuật toán
Thuật toán preSo:
Input :
• Xâu mẫu pat độ dài M
• Mảng S để lưu giá trị dạng bit ứng với các ký tự trong mẫu
Output:
• Giá trị biểu hiện vị trí của từng chữ cái trong xâu mẫu x
Formats: int preSo(char x[], int m, int S[])
Actions:
int j, lim;
int i;
for (i = 0; i < ASIZE; ++i)
S[i] = ~0; //dao bit cua so 0
Trang 11• Xâu mẫu pat độ dài m
• Văn bản nguồn txt độ dài n
public void SO(char x[], int m, char y[], int n ,int[] S ) {
int lim, state;
if (state < lim) //do dai thoa man xau mau so 0 dich den vi tri cua lim
Trang 12- Thực hiện từ trái qua phải
- Có pha tiền xử lý với độ phức tạp O(m)
- Độ phức tạp thuật toán là O(n)
❖ Thuật toán PreKmp : (Thực hiện bước tiền xử lý)
Input :
• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
Output: Mảng giá trị kmpNext[].
Trang 13while (j > -1 && x[i] != x[j])
Kiểm nghiệm PreKmp(X, m, kmpNext[]) với X[]=”GCAGAGAG”, m=8.
i=? (i==8)? ( X[i] == X[j] ) ? j = ? kmpNext[i] = ?
j = -1 kmpNext[0] = 0
4 (‘A’==’C’) : False j = 0 kmpNext[4] = chưa xác định
6 (‘A’==’C’) : False j = 0 kmpNext[6] = chưa xác định
Kết luận : kmpNext = {0, 0, 0, 1, 0, 1, 0, 1}
❖ Thuât toán Apostolico Crochemore
Input :
• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
• Văn bản Y =(y0, y1, ,xn), độ dài n.
Output:
• Tất cả vị trí xuất hiện X trong Y.
Formats:
Trang 14ApostolicoCrochemore (X, m, Y, n);
Actions:
Bước 1( Tiền xử lý):
preKmp(x, m, kmpNext); //Tiền xử lý với độ phức tạp O(m)
for (ell = 1; x[ell - 1] == x[ell]; ell++);
Trang 151.6 Not So Naive algorithm
❖ Đặc điểm :
- Thực hiện từ trái qua phải
- Độ phức tạp thuật toán là O(n*m)
- Thực hiện so sánh theo thứ tự vị trí 1, 2, 3, …m-2, m-1, 0.
❖ Thuật toán Not So Naive
Trang 16Input :
• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
• Văn bản Y =(y0, y1, ,xn), độ dài n.
Trang 17Phần 2 : Các thuật toán tìm kiếm mẫu từ bên phải qua bên trái
2.1 Thuật toán Booyer-Moore
a Đặc điểm
● Thực hiện từ phải qua trái
● Pha tiền xử lý độ phức tạp thời gian và không gian là O( m + ⌠ )
● Pha tìm kiếm độ phức tạp thời gian là O(mn)
b.Thuật toán
Thuật toán preBmBc:
Trang 18for (i = 0; i < ASIZE; ++i)
bmBc[i] = m; //gan cac gia tri trong mang = m
Trang 19• Mảng chứa giá trị xâu hậu tố dài nhất
Formats: suffixes(char *x, int m, int *suff)
Trang 20Thuật toán preBmGs
Input :
• Xâu mẫu x độ dài m
Output:
• Mảng chứa vị trí có hậu tố trùng nhau hoặc có phần chung giữa 2 xâu
Formats: preBmGs(char *x, int m, int bmGs[])
Trang 21for (i = m - 1; i >= 0 && x[i] == y[i + j]; i); //chay het doan trung nhau
if (i < 0) { //ca xau mau da trung khop
cout<<j;
Trang 22j += bmGs[0]; //dich den vi tri xuat hien .
BmGs[i] BmBc[y[i+j]] bmBc[y[i + j]] - m + 1 + i x[i] == y[i + j]
Trang 230(no) 5(yes) x[0]==y[5]
- Là cải tiếncủa thuật toán Boyer_Moore
- Thực hiện từ phải sang trái
- Có pha tiền xử lý với độ phức tạp O(m+σ)
- Độ phức tạp thuật toán là O(n)
❖ Thuật toán preBmBc: //thực hiện bước tiền xử lý bad-character shift
Trang 24• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
Output: mảng giá trị suff[].
if (i < g)
g = i;
f = i;
while (g >= 0 && x[g] == x[g + m - 1 - f])
Trang 25g;
suff[i] = f - g;
} }
Trang 27Kết luận : bmGs[] = {7, 7, 7, 2, 7, 4, 7, 1}
❖ Thuật toán Turbo-BM:
Input :
• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
• Văn bản Y =(y0, y1, ,xn), độ dài n.
Trang 28shift = bmGs[0];
u = m - shift;
} else {
v = m - 1 - i;
turboShift = u - v;
bcShift = bmBc[y[i + j]] - m + 1 + i;
shift = max(turboShift, bcShift);
shift = max(shift, bmGs[i]);
if (shift == bmGs[i])
u = min(m - shift, v);
else {
if (turboShift < bcShift) shift = max(shift, u + 1);
u = 0;
} }
Trang 29Kết quả : X xuất hiện trong Y tại vị trí 5.
Phần 3 : Các thuật toán tìm kiếm mẫu từ một vị trí cụ thể
3.1 Thuật toán skip-search
a Đặc điểm
● Sử dụng 1 ô chứa vị trí của mỗi ký tự
● Pha tiền xử lý độ phức tạp thời gian & độ phức tạp không gian là O( m + ⌠ )
● Pha tìm kiếm độ phức tạp thời gian là O(mn)
Trang 30số biểu thi cho thứ tự node
i ptr->next ptr->element z[x[i]]
Trang 3123+8 >y.length dừng
Phần 4: Các thuật toán tìm kiếm mẫu từ bất kỳ
4.1 Thuật toán Horspool
a Đặc điểm
● Một dạng đơn giản của thuật toán Boyer -Moore
● Pha tiền xử lý độ phức tạp thời gian là O( m + ⌠ ) độ phức tạp không gian là O(⌠)
● Pha tìm kiếm độ phức tạp thời gian là O(mn)
for (i = 0; i < ASIZE; ++i)
bmBc[i] = m; //gan cac gia tri trong mang = m
Trang 32• Độ dài xâu mẫu m
• Văn bản nguồn y độ dài n
Trang 33(no)5(yes) Y[13]=B B(yes) “ABAACABA” vs “ABACDABA”
● Thực hiện dịch giống thuật toán Horspool
● Pha tiền xử lý độ phức tạp thời gian là O( m + ⌠ ) độ phức tạp không gian là O(⌠)
● Pha tìm kiếm độ phức tạp thời gian là O(mn)
Trang 34• Độ dài xâu mẫu m
• Văn bản nguồn y độ dài n
if (lastCh == c && middleCh == y[j + m/2] &&
firstCh == y[j] &&
Kiểm nghiệm Raita:
j y[i+m-1] y[j + m/2] y[j] ghi chú
dịch 1 (bmBc[A])
Trang 35• Thực hiện việc so sánh từ phải sang trái.
• Giai đoạn tiền xử lý (preprocessing) có độ phức tạp thời gian và không gian là O(m+σ).
• Độ phức tạp O(m.n).
Trình bày thuật toán
Thuật toán preQsBc: //thực hiện bước tiền xử lý
Input :
• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
Output: Mảng giá trị QsBc [].
Formats:
Trang 36preQsBc(char *x, int m, int qsBc[])
• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
• Văn bản Y =(y0, y1, ,xn), độ dài n.
Trang 38• Thực hiện việc so sánh từ phải sang trái.
• Giai đoạn tiền xử lý (preprocessing) có độ phức tạp thời gian và không gian là O(m+σ).
• Độ phức tạp O(m.n).
Trình bày thuật toán
Thuật toán preBmBc: //thực hiện bước tiền xử lý
Trang 40}}
d.insert(d.begin()+j,0);
d.erase(d.begin()+j+1);
}}
l++;
if(d[0]==1){
Trang 41}if(kt(d,n)){
return a;
}}
a=m-k;
}i=i+a;
Trang 42• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
• Văn bản Y =(y0, y1, ,xn), độ dài n.
Void ZT(char *x, int m, char *y, int n){
Int i,j, ztBc[ASIZE][ASIZE], bmGs[XSIZE];
Trang 43j + = MAX(bmGs[i], ztBc[y[j + m -2]][y[j+ m-1]]);
}}
Trang 44for(int i=0;i<256;i++){
ztBc[i][p[0]]=m-1;
Trang 45}for(int i=1;i<m-1;i++){
ztBc[p[i-1]][p[i]]=m-1-i;
}}
int kt(string w, string p){
}
main(){
init();
Trang 46for(int i=0;i<m;i++){
suff.push_back(-1);
} suffixes(p,m);
preBmGs(p,m);
preZtBc(p,m);
xuli();
}
Kiểm nghiệm :
Y=GCATCGCAGAGAGTATACAGTACG
X=GCAGAGAG
ztBc A C G T
A 8 8 2 8
C 5 8 7 8
G 1 6 7 8
T 8 8 7 8
i 0 1 2 3 4 5 6 7
X[i] G C A G A G A G bmGs[i] 7 7 7 2 7 4 7 1
4.7 Thuật toán Berry Ravindran
Input :
• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
• Văn bản Y =(y0, y1, ,xn), độ dài n.
Output:
Trang 47• Tất cả vị trí xuất hiện X trong Y.
Trang 484.8 Thuật toán Tuned Boyer-Moore:
Input :
• Xâu mẫu X =(x0, x1, ,xm), độ dài m.
• Văn bản Y =(y0, y1, ,xn), độ dài n.
void TUNEDBM(char *x, int m, char *y, int n) {
int j, k, shift, bmBc[ASIZE];
Trang 49=5
k = bmBc[y[13]]=
bmBc[B]=0J=5+0
=5
k = bmBc[y[13]]=
bmBc[B]=0
“ABACDABA” (no)J=5<n=20 (yes)7(yes)
bmBc[B]=0J=8+0
=8
k = bmBc[y[16]]=
bmBc[B]=0J=8+0
=8
k = bmBc[y[16]]=
bmBc[B]=0
“CDABAACA” (no)
Trang 500=21
k = bmBc[y[29]]=
bmBc[B]=0J=21+
0=21
k = bmBc[y[29]]=
// gán mang bmBc tu x[0]->x[m-1] = i con lai la m
for (i = 0; i < ASIZE; ++i)
void TUNEDBM(char *x, int m, char *y, int n) {
int j, k, shift, bmBc[ASIZE];