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]}
}