Tải bản đầy đủ (.doc) (15 trang)

Tiểu Luận Thuật Toán boyer moore

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (253.84 KB, 15 trang )

MỤC LỤC
MỤC LỤC

1

I – GIỚI THIỆU

2

II- THUẬT TOÁN BOYER MOORE

2

III- SỐ PHÉP GÁN VÀ SO SÁNH 7
IV – ĐỘ PHỨC TẠP CỦA THUẬT TOÁN 10
V- KẾT LUẬN:

13

VI – TÀI LIỆU THAM KHẢO

13

1


I – GIỚI THIỆU
Thuật toán Boyer-Moore được đưa ra năm 1977 để kiểm tra, tìm kiếm
xâu cho một văn bản T[1,2,…,n] có chiều dài n với mỗi T[i] là một kí tự
trong bảng chữ cái (alphabet) với kích thước là 256 ký tự khác nhau. và một
xâu mẫu P[1,2,…,m] có chiều dài m (m≤n). Tìm (các) vị trí xuất hiện của


xâu P (như là một xâu liên con liên tục) trong văn bản T.
Như vậy, thuật toán Boyer-Moore sẽ đối sánh T và P theo chiều từ phải
sang trái của P. Bằng cách áp dụng thêm luật kí tự tồi (bad character rule) và
luật hậu tố tốt.
II- THUẬT TOÁN BOYER MOORE
1. Luật kí tự tồi:
Xuất hiện sự khác nhau giữa mẫu P và văn bản T: b = T [i+ j]# P[ i]=,
ta sẽ dịch sao cho có một ký tự giống b trên mẫu khớp vào vị trí đó, nếu có
nhiều vị trí xuất hiện b trên mẫu ta chọn vị trí bên phải nhất. Nếu không có ký
tự b nào trong mẫu ta sẽ dịch sao cho ký tự trái nhất của mẫu vào vị trí ngay
sau ký tự T [i+ j]= b để đảm bảo sự ăn khớp. Hai hướng tiếp cận sẽ tạo ra 2
giá trị dịch chuyển khác nhau, từ đó sẽ lựa chọn giá trị lớn hơn làm giá trị
dịch chuyển.
Trước hết chúng ta hãy xem xét ví dụ sau để hiểu luật này.
T=FINDIFAHAYXEACKNEXDLET=FINDIFAHAYXEACKNEXDLE
P=NEXDLEP
Tại bước đầu tiên (i=1)so sánh T[1,2,…,6] với P[1,2,…,6] ta thấy
rằng T[6]≠P[6] (chú ý ta so sánh từ phải sang trái của P). Do T[6]∉P, ta ngay
lập tức có thể dịch P lên 6 đơn vị và bắt đầu so sánh T[7,8,…,12] với P[1,2,
…,6]
Tại bước này ta sẽ gặp vị trí không khớp T[11]≠P[5], vì T[11]=P[3], ta sẽ
dịch P lên 2 đơn vị để cho T[11] thẳng hàng với P[3] và tiếp tục so sánh T[9,
…,14] với P[1,2,…,6]

2


Tại bước này, T[14]≠P[6] và T[14]∉P, ta dịch P lên 6 đơn vị và so sánh
T[15,…,20] với P[1,2,…,6]].
Tiếp tục các bước như trong hình vẽ dưới đây, cuối cùng ta tìm được

mẫu P ở vị trí i=16.

1

2

F I

3

4

5

N D I

6

7

8

9

10

11

12


13

14

15

16

17

18

19

20

21

F A H A Y X E A C K N E X D L E

N E X D L E
N E X D L E
N E X D L E
N E X D L E
N E X D L E

Hình 1 – Quá trình so khớp mẫu P=”NEXDLE” của thuật toán Boyer-Moore
Luật kí tự tồi: Dịch P lên một số x đơn vị sao cho kí tự tồi T[k] khớp
với kí tự P[s] là kí tự xuất hiện gần với P[m] nhất (s lớn nhất). Nếu s>js>j
hoặc không tồn tại kí tự P[s] như vậy thì ta dịch P lên 1.

Để thực thi luật kí tự tồi, với mỗi kí tự ∈Σ, gọi R[σ] là vị trí xuất hiện của kí
tự σgần với P[m] nhất. Nếu σ∉P, R[σ]=0. Theo quy luật kí tự tồi, mỗi bước
chúng ta sẽ dịch P một đoạn là: max(1,j−R[T[k]])

3


Index
x 2
x 1
x 4
x 4
x 4
x 4

Hình 2 – Quá trình dịch P lên một số x đơn vị

Thủ tục thuật giả mã của thuật toán BM sử dụng luật kí tự tồi như
sau:
int BMmatcher(int n, int m){
badCharBackup(m);
int i = 1, j = 0, p = 0, skip = 0;
while(i <= n-m+1){
skip = 0;
j = m;
while(j >= 1 && skip == 0){
if(T[i+j-1] != P[j]){
p = T[i+j-1]-96;
skip = max(1, j - R[p]);
}

j--;
}
if(skip == 0) {

4


return i;
}
i = i + skip;
}
return -1;
}
void badCharBackup(int m){
int i = 0;
memset(R, 0, sizeof(R));
for(i = 1; i <= m; i++){
R[P[i] - 96] = i;
}
}
2. Luật hậu tố tốt (Good suffix rule)
Luật hậu tố tốt chúng ta phát biểu trong phần này mạnh hơn phát biểu
gốc cuả thuật toán Boyer-Moore.
Luật hậu tố tốt: Giả sử khi so sánh, một xâu con Tsub của văn
bản T khớp với hậu tố của mẫu P, nhưng kí tự liền kề bên trái của Tsub không
khớp với kí tự tương ứng trong P. Tìm một xâu con tsub (nếu có) phải nhất
(right most-- gần với kí tự cuối P[m] nhất) của P thỏa mãn: tsub không phải
là hậu tố của P và kí tự liền kề bên trái của tsub khác với kí tự liền kề bên trái
của hậu tố Tsub của P. Dịch P sao cho tsub khớp với Tsub trong T.
Nếu tsub không tồn taị, dịch P một số lượng ít nhất sao cho kí tự đầu

tiên của P vượt quá kí tự đầu tiên của Tsub và tiền tố của P khớp với hậu tố
của Tsub. Nếu không thể dịch P để thỏa mãn điều kiện đó, dịch P lên m đơn vị
Trường hợp ta tìm tất cả sự xuất hiện của P trong T, sau khi đã tìm thấy P, ta
dịch P một lượng ít nhất (> 0) sao cho tiền tố của P khớp với hậu tố
của P trong T. Trong trường hợp không thể dịch như vậy, dịch P lên m đơn vị.

5


Xét ví dụ sau:
T[1,2,…,30]= C G T G C C T A C T T A C T T A C T T A C T T A C G C G A
A

và P[1,2,…,9]= C T T A C T T A C khi so sánh T với P, nhận

thấy Tsub={TAC}=T[7,8,9], và cũng tìm được Tsub=(TAC)=P[3,4,5], ta có
thể dịch 4 đơn vị để khớp với Tsub..

Hình 3: so sánh P với T theo luật Good suffix rule

Thủ tục thuật giả mã của thuật toán BM sử dụng luật kí tự tồi như sau:
int fastfastBMmatcher(int n, int m){
computeLL(m, LL, Zbar);
computeSL(m, SL, Zbar);
while(i <= n-m+1){
skip = 0;
j = m;
while(j >= 1 && skip == 0){
if(T[i+j-1] != P[j]){
p = T[i+j-1]-96;

skip = max(1, j - R[p]);
if(j!=m){
if(LL[j+1] !=0){
6


skip = max(skip, m - LL[j+1]);
} else {
skip = max(skip, m - SL[j+1]);
}
}
}
j--;
}
if(skip == 0) return i;
i = i + skip;
}
return -1;

}
void computeLL(int m, int *LL, int *Zbar){
int i = 0, j = 0;
char Prev[m+1];
int Zrev[m+1];
for(i = m; i >= 1; i--){
Prev[m-i+1] = P[i];
}
compute_Z_function(Prev, Zrev, m);
for(i = 1; i<= m-1; i++){
Zbar[i] = Zrev[m-i+1];

}
for(j = 1; j <= m-1; j++){
i = m - Zbar[j]+1;
LL[i] = j;
}
}
void computeSL(int m, int *SL, int *Zbar){

7


int i = 1,j = 0;
for(i = 1; i

<= m-1; i++){

if(Zbar[i] == i){
SL[m-i+1] = i;
j = i;
} else {
SL[m-i+1] = j;
}
}}
III- SỐ PHÉP GÁN VÀ SO SÁNH
1. Số phép gán
50
100
150
200
250

300
350
400
450
500
550
600
650
700
750
800
850
900
950
1000

113.46
100.78
102.42
89.21
46.86
70.17
29.74
49.45
45.15
19.42
22.00
21.35
14.62
20.25

15.96
13.54
17.67
15.17
14.39
16.71

102.25
101.11
83.28
72.92
56.74
45.83
48.35
38.34
35.15
35.95
29.21
23.71
19.93
19.13
14.85
16.57
14.15
14.59
14.72
13.40

88.68
89.66

81.29
88.50
61.94
43.98
52.58
37.58
37.32
26.88
23.29
15.67
16.53
16.39
13.81
16.66
14.41
12.76
16.14
14.83

82.27
83.91
87.64
88.49
58.62
55.88
55.27
29.29
34.45
34.35
29.83

21.23
20.20
19.04
14.64
15.07
15.74
14.40
13.91
14.65

89.72
103.99
81.33
78.86
57.62
49.93
37.43
37.24
34.95
28.60
26.24
23.26
19.26
17.31
16.13
15.41
12.79
13.88
13.69
12.92


87.62
89.13
77.24
81.59
57.69
45.63
46.14
34.17
33.78
32.25
23.60
20.44
17.68
19.66
14.42
15.04
13.71
13.18
14.51
14.32

173.85
175.76
159.14
173.32
120.45
84.42
101.64
71.66


160.96
164.35
171.69
173.48
113.66
108.14
106.97
55.12

175.73
204.45
159.13
154.34
111.64
96.43
71.30
70.94

171.63
174.77
151.02
159.60
111.96
87.70
88.81
64.81

102.93
101.59

79.77
70.83
59.04
49.21
49.57
38.65
34.66
36.98
23.97
21.26
17.28
19.47
15.83
16.55
14.11
15.99
14.50
13.23

81.98
93.30
91.12
82.85
52.55
54.75
44.64
33.43
31.41
30.35
23.91

20.53
16.74
19.06
17.53
15.56
15.30
15.78
13.66
13.41

92.28
85.16
77.11
83.40
57.71
45.51
42.27
40.20
31.28
30.04
24.24
21.30
17.88
15.90
15.67
15.80
15.55
14.21
14.29
13.76


98.89
93.20
73.93
79.98
59.91
50.93
46.96
34.79
35.47
31.44
23.81
21.12
17.18
18.43
15.68
16.05
15.80
14.64
14.76
13.78

b. Số phép so sánh
50
100
150
200
250
300
350

400

223.10
198.21
201.31
174.89
90.25
136.75
56.20
95.52

201.00
198.77
162.97
142.38
109.93
88.14
93.09
73.00

202.14
199.60
156.06
138.17
114.57
94.96
95.63
73.75

160.49

183.10
178.63
162.17
101.61
105.94
85.84
63.37

180.96
166.82
150.75
163.27
111.93
87.52
81.06
76.86

194.17
182.89
144.45
156.41
116.27
98.32
90.41
66.06
8


450
500

550
600
650
700
750
800
850
900
950
1000

86.69
35.52
40.42
39.35
26.04
36.94
28.48
23.70
31.72
26.87
25.37
29.98

66.67
68.44
54.88
43.95
36.34
34.66

26.26
29.55
24.98
25.72
26.09
23.39

71.05
50.14
43.11
27.94
29.54
29.38
24.17
29.71
25.37
22.02
28.70
26.14

65.44
65.22
56.04
38.94
36.91
34.50
25.89
26.64
27.98
25.32

24.30
25.79

66.49
53.71
49.01
42.98
34.96
31.18
28.71
27.45
22.24
24.29
23.93
22.37

64.01
60.96
43.70
37.39
31.81
35.73
25.42
26.60
24.00
22.90
25.41
25.18

65.89

70.36
44.47
39.08
31.02
35.40
28.15
29.56
24.81
28.40
25.59
23.01

59.39
57.21
44.29
37.58
29.98
34.57
31.50
27.61
27.10
28.01
23.87
23.35

59.08
56.51
45.00
39.16
32.17

28.35
27.84
28.10
27.60
24.90
25.13
24.11

67.37
59.36
44.09
38.69
30.86
33.31
27.79
28.57
27.97
25.81
26.03
24.12

V- KỲ VỌNG, PHƯƠNG SAI, ĐỘ LỆCH CHUẨN, ĐỒ THỊ
5.1 Số phép gán
n

Kỳ vọng

Phương sai

Độ lệch chuẩn


Chặn trên

Chặn dưới

50
100

93.805

105.30705

10.26192233

104.06692

83.54308

93.518

53.33526222

7.303099494

100.8211

86.2149

150


78.37

62.7362

7.920618663

86.290619

70.44938

200

74.838

38.39226222

6.196148983

81.034149

68.64185

250

54.209

14.39016556

3.793437169


58.002437

50.41556

300

48.789

60.87896556

7.802497392

56.591497

40.9865

350

40.685

49.50216111

7.035777222

47.720777

33.64922

400


33.315

25.74407222

5.073861668

38.388862

28.24114

450

29.889

7.19681

2.682687086

32.571687

27.20631

500

24.514

18.51593778

4.303014964


28.817015

20.21099

550

19.498

7.965373333

2.822299299

22.320299

16.6757

600

16.447

3.30289

1.817385485

18.264385

14.62961

650


15.233

1.799867778

1.341591509

16.574592

13.89141

700

14.119

3.123298889

1.767285741

15.886286

12.35171

750

13.45

0.309622222

0.556437078


14.006437

12.89356

800

13.238

0.675173333

0.821689317

14.059689

12.41631

850

12.906

2.103804444

1.450449739

14.35645

11.45555

900


12.728

0.709995556

0.84261234

13.570612

11.88539

950

12.662

0.346595556

0.588723667

13.250724

12.07328

1000

12.623

0.454378889

0.674076323


13.297076

11.94892

Đồ thị biểu diễn

9


5.2 Số phép so sánh

n

Kỳ vọng

Phương sai

Độ lệch chuẩn

Chặn trên

Chặn dưới

50
100

185.514

420.6064267


20.5086915

206.022691

165.00531

185.034

213.2170933

14.6019551

199.635955

170.43204

150

154.738

250.8875511

15.8394303

170.57743

138.89857

200


147.672

153.6067067

12.3938173

160.065817

135.27818

250

106.421

57.52832111

7.58474265

114.005743

98.836257

300

95.578

243.4937511

15.6042863


111.182286

79.973714

350

79.364

198.1224044

14.0755961

93.4395961

65.288404

400

64.628

102.9767067

10.1477439

74.7757439

54.480256

450


57.772

28.71646222

5.35877432

63.1307743

52.413226

500

47.024

74.04389333

8.60487614

55.6288761

38.419124

550

36.991

31.93743222

5.65132128


42.6423213

31.339679

600

30.894

13.20982667

3.63453252

34.5285325

27.259467

650

28.463

7.203512222

2.68393596

31.146936

25.779064

700


26.237

12.49275667

3.5345094

29.7715094

22.702491

750

24.897

1.233356667

1.11056592

26.0075659

23.786434

800

24.48

2.706666667

1.64519502


26.125195

22.834805

850

23.813

8.394756667

2.89737065

26.7103706

20.915629

900

23.45

2.838622222

1.68482112

25.1348211

21.765179

950


23.325

1.387383333

1.17787238

24.5028724

22.147128

1000

23.244

1.81496

1.34720451

24.5912045

21.896795

Đồ thị biểu diễn

10


IV – ĐỘ PHỨC TẠP CỦA THUẬT TOÁN
Xét tổng quát chương trình sau:
int BMmatcher(int n, int m){

int R[28];
int Zbar[MAXM];
int LL[MAXM];
int SL[MAXM];
badCharBackup(m);
int i = 1, j = 0, p = 0, skip = 0;
computeLL(m, LL, Zbar);
computeSL(m, SL, Zbar);
while(i <= n-m+1){
skip = 0;
j = m;
while(j >= 1 && skip == 0){
if(T[i+j-1] != P[j]){
p = T[i+j-1]-96;
skip = max(1, j - R[p]);
if(j!=m){
if(LL[j+1] !=0){
11


skip = max(skip, m - LL[j+1
} else {
skip = max(skip, m - SL[j+1
}
}
}
j--;
}
if(skip == 0) return i;
i = i + skip;

}
return -1;
}
1. Tính toán độ phức tập của chương trình con
Thực hiện tính toán trên số phép so sánh
void badCharBackup(int m) {
int i = 0;
for (i = 0; i < m; i++) {

m+1 lần

R[P[i] - 26] = i;
}
Vậy độ phức tạp O(m+1)
2. Tính toán độ phức tạp của chương trình con
Thực hiện tính toán trên số phép so sánh
void computeLL(int m, int *LL, int *Zbar){
for(i = 1; i<= m-1; i++){

m lần

Zbar[i] = Zrev[m-i+1];
}
for(j = 1; j <= m-1; j++){

m lần

i = m - Zbar[j]+1;

12



LL[i] = j;
}
}
Thực hiện tính toán trên số phép so sánh
void computeSL(int m, int *SL, int *Zbar){
int i = 1,j = 0;
for(i = 1; i <= m-1; i++){

m lần

if(Zbar[i] == i){

m lần

SL[m-i+1] = i;
j = i;
} else {
SL[m-i+1] = j;
}
}
}
Vậy ta tính được độ phức tạp của chương trình trên là O(4m)
3. Tính độ phức tạp trong chương trình chính
Thực hiện tính toán trên số phép so sánh
BOYERMOORE(int
while(i <= n-m+1){

n,


int

m){

n-m+2

skip = 0;
j = m;
while(j >= 1 && skip == 0){
if(T[i+j-1] != P[j]){

m(n-m+2)+1
m(n-m+2)

p = T[i+j-1]-96;
skip = max(1, j - R[p]);
if(j!=m){
if(LL[j+1] !=0){

m(n-m+2)
m(n-m+2)

13


skip = max(skip, m - LL[j+1
} else {
skip = max(skip, m - SL[j+1
}

}
}
j--;
}
if(skip == 0) return i;

m(n-m+2)

i = i + skip;
}
}
Vậy ta tính được độ phức tạp là O(n-m+1 +m(n-m+1)+1+4(m(n-m)))
=O(5(m(n-m)+n+1)
Tổng kết lại ta có: O (m+1) +O(4m)+ O(5(m(n-m)+n+1)
Kết luận: vậy độ phức tạp của thuật toán là O(m*n)
V- KẾT LUẬN:

Thuật toán Boyer Moore là thuật toán tìm kiếm chuỗi rất có hiệu quả
trong thực tiễn, các dạng khác nhau của thuật toán này thường được cài đặt
trong các chương trình soạn thảo văn bản.
Các đặc điểm chính của nó: 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
+C). Giai đoạn tìm kiếm có độ phức tạp lớn nhất O(m*n).
Thuật toán Boyer-Moore có thể đạt tới chi phí O(n/m) là nhờ có cách
dịch thứ 2 “ký tự không khớp”. Cách chuyển cửa sổ khi gặp “ký tự không
khớp” cài đặt vừa đơn giản lại rất hiệu quả trong các bảng chữ cái lớn nên có
nhiều thuật toán khác cũng đã lợi dụng các quét mẫu từ phải sang trái để sử
dụng cách dịch này.

14



Tuy nhiên có một vài thuật toán đã cải tiến cách dịch này để đưa đến
chi phí tính toán của thuật toán Boyer-Moore là tuyến tính như: BMH (BMHorspool) [1] đưa ra năm 1980 dùng cho tập đơn mẫu. CW (Commentz &
Walter) [10] đưa ra năm 1979, SBMH [11] năm 2002 và YBHK [12] năm
2003, WM (Wu & Manner) năm 1994 dùng cho tập đa mẫu. Với CW thì độ
phức tạp thời gian trong trường hợp tốt nhất với tập p mẫu là: O(n*max{m[0],
m[1],... m[p-1]}) còn trong trong trường hợp tốt nhất thời gian thực thi là
O(n/min{m[0], m[1],... m[p-1]}) với m[i] là độ dài của mẫu thứ i
VI – TÀI LIỆU THAM KHẢO
[1] Boyer, Robert S., and J. Strother Moore. A fast string searching
algorithm. Communications of the ACM 20.10 (1977): 762-772.
[2]
[3]

15



×