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

Phân tích và đánh giá thuật toán thuật toán đối sánh mẫu aho corasick

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 (344.4 KB, 25 trang )

KHOA CÔNG NGHỆ THÔNG TIN
_______________ _______________


BÀI TẬP LỚN MÔN HỌC
MÔN HỌC: PHÂN TÍCH VÀ ĐÁNH GIÁ THUẬT TOÁN
ĐỀ TÀI: THUẬT TOÁN ĐỐI SÁNH MẪU AHO-CORASICK

Người hướng dẫn : TS Đào Thanh Tĩnh
Người thực hiện : Hồ Sỹ Tấn
Lớp : CHHTTT25B13

HÀ NỘI, THÁNG 05 - 2014


Thuật toán đối sánh mẫu Aho-Corasick

LỜI NÓI ĐẦU
Hiện nay, máy tính đã thâm nhập vào hầu hết các lĩnh vực của xã hội. Việc
số hóa dữ liệu, lưu trữ và xử lý các văn bản trên máy tính là một việc làm hết
sức quan trọng.
Trong một hệ xử lý văn bản, các thuật toán xử lý xâu ký tự được coi là yếu
tố quan trọng trong việc nâng cao hiệu quả về thời gian, độ chính xác khi xử lý
một văn bản. Trong các phép toán cơ bản trên chuỗi ký tự, phép toán đối sánh
chuỗi luôn được chú trọng phát triển, đặc biệt là trong điều kiện các dữ liệu văn
bản ngày càng nhiều.
Bài toán đối sánh chuỗi ký tự có thể được đặc trưng như một bài toán tìm
kiếm, trong đó mẫu P được xem như khoá, tuy nhiên các thuật toán tìm kiếm
thông thường không áp dụng được một cách trực tiếp vì mẫu P có thể dài và nó
trải trên văn bản theo một cách không biết trước. Đây là một bài toán thú vị và
đã có nhiều thuật toán khác nhau được đưa ra để giải quyết nó như Brute-Force


(BF), Knuth-Morris-Pratt (KMP), Aho-Corasick, Boyer-Moore (BM), KarpRabin (KR), Franek-Jennings-Smyth (FJS),…
Trong báo cáo này, chúng tôi đi giới thiệu và phân tích về thuật toán AhoCorasick (AC), một thuật toán được cho là tương đối hiệu quả và đang được ứng
dụng trong nhiều lĩnh vực liên quan đến tìm kiếm nội dung thông tin hiện nay.
Mặc dù chúng tôi đã rất nổ lực trong việc tìm hiểu, nghiên cứu và tập hợp
thông tin cũng như thi công chương trình minh họa. Nhưng do thời gian và kinh
nghiệm hạn chế nên trong báo cáo sẽ không tránh khỏi những thiếu sót, rất
mong các thầy cô giáo và các học viên cùng khóa đóng góp để chúng tôi tiếp tục
hoàn thiện nội dung nghiên cứu.

2


Thuật toán đối sánh mẫu Aho-Corasick

MỤC LỤC
LỜI NÓI ĐẦU.................................................................................................................................................. 2
MỤC LỤC....................................................................................................................................................... 3
PHẦN I - KHÁI NIỆM CƠ BẢN VỀ ĐỐI SÁNH CHUỖI KÝ TỰ................................................................................4
1. GIỚI THIỆU
4
2. BÀI TOÁN ĐỐI SÁNH MẪU
4
3. MỘT SỐ THUẬT TOÁN ĐỐI SÁNH MẪU
5
3.1. Thuật toán Brute Force.............................................................................................................................5
3.2. Thuật toán Knuth-Morris-Prat................................................................................................................5
3.3. Thuật toán automat hữu hạn...................................................................................................................5
3.4. Thuật toán Boyer-Moore..........................................................................................................................5
3.5. Thuật toán Karp-Rabin.............................................................................................................................6
3.6. Các thuật toán khác..................................................................................................................................6

PHẦN II - THUẬT TOÁN AHO-CORASICK.......................................................................................................... 7
1. GIỚI THIỆU VỀ THUẬT TOÁN
7
2. PHÂN TÍCH THUẬT TOÁN
7
2.1. Máy tìm kiếm mẫu...................................................................................................................................7
2.2. Xây dựng hàm goto, failure và output...................................................................................................10
2.3. Đánh giá độ phức tạp của thuật toán....................................................................................................14
3. ỨNG DỤNG CỦA THUẬT TOÁN AHO-CORASICK
16
3.1. Ứng dụng trong các hệ phát hiện xâm nhập (IDS).................................................................................16
3.2. Phát hiện đạo văn...................................................................................................................................17
3.3. Tin sinh học.............................................................................................................................................17
3.4. Kỹ thuật Forensics...................................................................................................................................17
3.5. Khai thác văn bản..................................................................................................................................18
PHẦN III - CÀI ĐẶT CHƯƠNG TRÌNH THỬ NGHIỆM........................................................................................ 19
1. MÔ TẢ CHƯƠNG TRÌNH THỬ NGHIỆM
3. CHẠY THỬ NGHIỆM CHƯƠNG TRÌNH
4. MỘT VÀI NHẬN XÉT VỀ CHƯƠNG TRÌNH THỬ NGHIỆM

19
20
23

KẾT LUẬN..................................................................................................................................................... 24
TÀI LIỆU THAM KHẢO................................................................................................................................... 25

3



Thuật toán đối sánh mẫu Aho-Corasick

PHẦN I - KHÁI NIỆM CƠ BẢN VỀ ĐỐI SÁNH CHUỖI KÝ TỰ
1. GIỚI THIỆU
Trong các hệ xử lý văn bản chuỗi ký tự được coi là thành phần trung tâm,
các hệ xử lý văn bản cung cấp nhiều thuật toán đóng vai trò quan trọng trong
việc thao tác trên các chuỗi ký tự. Một phép toán cơ bản trên chuỗi ký tự là đối
sánh chuỗi ký tự (String Matching). Bài toán đặt ra như sau “Cho trước một
chuỗi văn bản T có độ dài n và một mẫu P có độ dài m, hãy tìm sự xuất hiện của
mẫu P trong văn bản T”.
Hầu hết các thuật toán cho bài toán này có thể dễ dàng mở rộng để tìm tất
cả các vị trí xuất hiện của mẫu P trong văn bản T, vì chúng sẽ quét qua toàn bộ
văn bản một cách tuần tự và có thể được bắt đầu trở lại ở thời điểm ngay sau
điểm bắt đầu của một lần xuất hiện để tìm tiếp lần xuất hiện tiếp theo của mẫu.
Bài toán đối sánh chuỗi ký tự có thể được đặc trưng như một bài toán tìm
kiếm, trong đó mẫu P được xem như khoá, tuy nhiên các thuật toán tìm kiếm
thông thường không áp dụng được một cách trực tiếp vì mẫu P có thể dài và nó
trải trên văn bản theo một cách không biết trước được. Đây là một bài toán thú
vị có nhiều thuật toán khác nhau như Brute-Force (BF), Knuth-Morris-Pratt
(KMP), Boyer-Moore (BM), Karp-Rabin (KR), Franek-Jennings-Smyth (FJS),


2. BÀI TOÁN ĐỐI SÁNH MẪU
Giả sử chúng ta có một văn bản T là một mảng có độ dài là n (T[1...n]) và
một chuỗi mẫu P có độ dài là m (P[1...m]). Các phần tử của T và P là các ký tự
trong tập hữu hạn alphabet Σ. VD: Σ = {0,9} hoặc Σ = {a,b,c...,z,A,B,C,…,Z}.
Mảng ký tự S và T được gọi là chuỗi ký tự.
Khi đó bài toán đối sánh chuỗi được phát biểu như sau: Cho một chuỗi ban
đầu T và một chuỗi mẫu P. Đối sánh chuỗi ký tự chính là việc tìm chuỗi mẫu P
trong chuỗi ban đầu T. Nếu chuỗi mẫu P được tìm thấy trong chuỗi ban đầu T

hãy chỉ ra vị trí trong T mà tại đó chuỗi mẫu P được tìm thấy.
Cụ thể hơn chuỗi mẫu P được tìm thấy trong T bắt đầu từ vị trí s+1 thì 0 ≤
s ≤ n-m và T(s,...,s+m) = P(1...m) tức là T(s + j) = P(j) với 1≤ j ≤ m và s được
gọi là giá trị dịch chuyển. Còn trong trường hợp ngược lại (tức là không tìm thấy
mẫu P trong T), s được gọi là giá trị dịch chuyển không hợp lệ.

4


Thuật toán đối sánh mẫu Aho-Corasick

3. MỘT SỐ THUẬT TOÁN ĐỐI SÁNH MẪU
3.1. Thuật toán Brute Force
Thuật toán so sánh tuần tự giản đơn (Brute Force) thử kiểm tra tất cả các vị
trí trên văn bản từ 0 cho đến n-m. Sau mỗi lần thử thuật toán Brute Force dịch
mẫu sang phải một ký tự cho đến khi kiểm tra hết văn bản. Thuật toán Brute
Force không cần giai đoạn tiền xử lý cũng như các mảng phụ cho quá trình tìm
kiếm. Độ phức tạp tính toán của thuật toán này là O(n*m).
3.2. Thuật toán Knuth-Morris-Pratt
Thuật toán Knuth-Morris-Pratt (KMP) là thuật toán có độ phức tạp tuyến
tính đầu tiên được phát hiện ra, dựa trên thuật toán Brute Force với ý tưởng lợi
dụng lại những thông tin của lần thử trước cho lần sau. Trong thuật toán Brute
Force vì chỉ dịch cửa sổ đi một ký tự lên có đến m-1 ký tự của cửa sổ mới là
những ký tự của cửa sổ vừa xét. Trong đó có thể có rất nhiều ký tự đã được so
sánh giống với mẫu và bây giờ lại nằm trên cửa sổ mới nhưng được dịch đi về vị
trí so sánh với mẫu. Việc xử lý những ký tự này có thể được tính toán trước rồi
lưu lại kết quả. Nhờ đó lần thử sau có thể dịch đi được nhiều hơn một ký tự, và
giảm số ký tự phải so sánh lại.
3.3. Thuật toán automat hữu hạn
Trong lớp thuật toán dạng này, quá trình tìm kiếm được đưa về một quá

trình biến đổi trạng thái automat. Hệ thống automat trong thuật toán DFA sẽ
được xây dựng dựa trên xâu mẫu.
Mỗi trạng thái (nút) của automat lúc sẽ đại diện cho số ký tự đang khớp của
mẫu với văn bản. Các ký tự của văn bản sẽ làm thay đổi các trạng thái. Và khi
đạt được trạng cuối cùng có nghĩa là đã tìm được một vị trí xuất hiện ở mẫu.
Việc xây dựng hệ automat khá đơn giản khi được cài đặt trên ma trận kề.
Khi đó thuật toán có thời gian xử lý là O(n) và thời gian để tạo ra hệ automat là
O(m*n) (tùy thuộc vào cách cài đặt).
3.4. Thuật toán Boyer-Moore
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 điểm chính của thuật toán là kiểm tra các ký tự của mẫu từ phải sang
trái và khi phát hiện sự khác nhau đầu tiên thuật toán sẽ tiến hành dịch cửa sổ đi,
độ phức tạp về thời gian ở gian đoạn tiền xử lý là O(m+d), ở gian đoạn tìm mẫu
là O(m*n), trong trường hợp tốt nhất là O(n/m).
5


Thuật toán đối sánh mẫu Aho-Corasick
Trong thuật toán này có hai cách dịch cửa sổ:
Cách thứ 1: gần giống như cách dịch trong thuật toán KMP, dịch sao cho
những phần đã so sánh trong lần trước khớp với những phần giống nó trong lần
sau.
Cách thứ 2: Coi ký tự đầu tiên không khớp trên văn bản là b=y[i+j] ta sẽ
dịch sao cho có một ký tự giống b trên xâu mẫu khớp vào vị trí đó (nếu có nhiều
vị trí xuất hiện b trên xâu mẫu ta chọn vị trí phải nhất).
3.5. Thuật toán Karp-Rabin
Thuật toán Karp-Rabin là thuật toán sử dụng hàm băm, độ phức tạp về thời
gian trong giai đoạn tiền xử lý là O(m), giai đoạn tìm mẫu là O(m*n). Đây là bài

toán tìm kiếm mẫu không khác nhiều so với bài toán tìm kiếm chuẩn. Tại đây
một hàm băm được dùng để tránh đi sự so sánh không cần thiết. Thay vì phải so
sánh tất cả các vị trí của văn bản, ta chỉ cần so sánh những cửa sổ bao gồm
những ký tự “có vẻ giống” mẫu.
3.6. Các thuật toán khác
Các thuật toán sánh mẫu theo thứ tự đặc biệt
- Thuật toán Galil-Seiferas và Crochemore-Perrin chia mẫu thành hai đoạn,
đầu tiên kiểm tra đoạn ở bên phải rồi mới kiểm tra đoạn bên trái với chiều từ trái
sang phải.
- Thuật toán Colussi và Galil-Giancarlo lại chia mẫu thành hai tập và tiến
hành tìm kiếm trên mỗi tập với một chiều khác nhau.
- Thuật toán Optimal Mismatch và Maximal Shift sắp xếp thứ tự mẫu dựa
vào mật độ của ký tự và khoảng dịch được.
- Thuật toán Skip Search, KMP Skip Search và Alpha Skip Search dựa sự
phân bố các ký tự để quyết đinh vị trí bắt đầu của mẫu trên văn bản.
Các thuật toán sánh mẫu theo thứ tự bất kỳ. Đó là các thuật toán có thể tiến
hành sánh mẫu với cửa sổ theo một thứ tự ngẫu nhiên. Đặc trưng là họ thuật
toán sánh mẫu văn bản Wu-Manbers (ký hiệu là WM) được Sun Wu và Udi
Manber công bố vào năm 1994 [WM94]. Các tác giả sử dụng các ý tưởng nhảy
của thuật toán BM do R. S. Boyer và J. S. Moore [BM77] và hàm băm.

6


Thuật toán đối sánh mẫu Aho-Corasick

PHẦN II - THUẬT TOÁN AHO-CORASICK
1. GIỚI THIỆU VỀ THUẬT TOÁN
Thuật toán tìm kiếm chuỗi kết hợp Aho-Corasick được xây dựng bởi Alfred
V. Aho and Margaret J. Corasick. Đây là một thuật toán đơn giản và hiệu quả

được dùng để xác định số lần xuất hiện của một số từ khóa hữu hạn trong chuỗi
văn bản. Thuật toán này xây dựng máy trạng thái hữu hạn dựa vào các từ khóa
và sau đó sử dụng máy này để xử lý chuỗi văn bản. Thời gian xây dựng máy so
khớp mẫu phụ thuộc vào tổng độ dài của các từ khóa.
Thuật toán gồm 2 phần:
- Phần 1: Xây dựng máy so khớp mẫu trạng thái hữu hạn các từ khóa.
- Phần 2: Sử dụng máy so khớp mẫu vừa xây dựng để xử lý chuỗi văn bản.
Sử dụng máy trạng thái hữu hạn vào các ứng dụng so khớp mẫu tuy không
mới, nhưng công việc này dường như không được các nhà lập trình ưa chuộng,
nguyên nhân là sự phức tạp của chương trình thuật toán trong quá trình xây
dựng thiết bị tự động hữu hạn từ các biểu thức chính quy mà các biểu thức này
phải xây dựng kỹ thuật tối ưu hóa trạng thái. Phần này sẽ mô tả máy so khớp
mẫu trạng thái hữu hạn được xây dựng nhanh chóng và hiệu quả bằng cách hạn
chế các biểu thức chính quy mà các biểu thức này bao gồm các bộ từ khóa hữu
hạn. Phương pháp tiếp cận ở đây là sự kết hợp ý tưởng trong thuật toán KnuthMorris-Pratt với máy trạng thái hữu hạn.

2. PHÂN TÍCH THUẬT TOÁN
Phần phân tích này chủ yếu dựa trên bài báo: “Efficient string matching: An
aid to biblographic search - Alfray V.Aho and Margaret J.Corasick” [2]. Phần
này sẽ trình bày về máy so khớp chuỗi mẫu trạng thái hữu hạn để xác định các
từ khóa trong chuỗi văn bản. Phần tiếp theo sẽ mô tả thuật toán để xây dựng
máy này.
2.1. Máy tìm kiếm mẫu
Giả sử K={
} là bộ hữu hạn các từ khóa và x là chuỗi văn bản tùy
ý. Vấn đề ở đây là phải xác định và tìm ra tất cả các chuỗi con của x là các từ
khóa thuộc K. Các chuỗi con này có thể chồng chéo nhau.
Một máy so khớp mẫu là một chương trình với đầu vào chuỗi văn bản x và
đầu ra xác định từ khóa của tập K có xuất hiện trong x hay không. Máy tìm kiếm
mẫu bao gồm một bộ các trạng thái. Mỗi trạng thái đại diện bởi một số. Máy xử

lý chuỗi văn bản x bằng cách liên tục đọc các ký tự trong x, thay đổi trạng thái
và liên tục đưa ra kết quả . Máy này gồm có 3 hàm: goto g, failure f, và output.
7


Thuật toán đối sánh mẫu Aho-Corasick
Hình 1 biểu diễn máy so khớp mẫu trạng thái sử dụng các hàm với một bộ từ
khóa {he, she, his, hers}.

Hình 1: Máy so khớp mẫu trạng thái hữu hạn.
Trong Hình 1 có 9 trạng thái là 0,1,…, 9, trong đó trạng thái 0 luôn được
thiết kế là trạng thái bắt đầu. Hàm goto g ánh xạ với trạng thái và ký tự của trạng
thái đó hoặc thông báo fail. Hình 1(a) mô tả về hàm goto. Ví dụ, mũi tên trỏ từ
trạng thái 0 đến 1 được gán nhãn h nên g(0, h) = 1. Trái lại nếu không có mũi
tên này thì kết quả là fail. Do vậy với tất cả các ký tự đầu vào khác e và i thì
g(0, ) = fail. Tất cả các máy so khớp mẫu đều được xây dựng thỏa mãn g(0, )
fail với tất cả các ký tự đầu vào là . Chúng ta sẽ thấy đặc điểm này trong hàm
goto tại trạng thái 0 để đảm bảo rằng đối với mỗi ký tự đầu vào sẽ được máy so
khớp mẫu xử lý trong mỗi chu kỳ máy.
Hàm failure f ánh xạ một trạng thái vào một trạng thái. Hàm failure được
truy vấn bất cứ khi nào hàm goto trả về kết quả fail. Khi trạng thái đầu ra đã xác
định có nghĩa là tập từ khóa được tìm thấy. Hàm output là sự kết hợp của một bộ
các từ khóa (có thể rỗng) với mỗi trạng thái.
Một chu kỳ hoạt động của một máy so khớp mẫu được định nghĩa như sau.
Giả sử s là trạng thái hiện tại của máy và a là ký tự hiện tại của chuỗi văn bản
đầu vào x.
1. Nếu g(s, a) = s', máy sẽ thực hiện goto transition (quá trình chuyển tiếp
của hàm goto). Máy sẽ nhập vào trạng thái s' và ký tự tiếp theo của x là ký tự
8



Thuật toán đối sánh mẫu Aho-Corasick
đầu vào hiện tại. Ngoài ra, nếu output(s') empty thì vị trí của ký tự đầu vào
hiện tại là kết quả của hàm output(s'). Một chu kỳ hoạt động kết thúc.
2. Nếu g(s, a) = fail, máy sẽ gọi hàm failure và thực hiện quá trình chuyển
tiếp của hàm fail. Nếu f(s) = s', máy sẽ lặp lại chu kỳ hoạt động với s' là trạng
thái hiện tại và a là ký tự đầu vào hiện tại.
Ban đầu, trạng thái hiện tại của máy là trạng thái bắt đầu và ký tự đầu tiên
của chuỗi văn là ký tự đầu vào hiện tại. Sau đó máy sẽ xử lý chuỗi văn bản bằng
cách tạo ra một chu kỳ hoạt động cho mỗi ký tự của chuỗi văn bản.
Ví dụ, máy M sử dụng các hàm trong hình 1 để xử lý chuỗi văn bản
"ushers". Hình 2 mô tả máy M thực hiện chuyển tiếp trạng thái trong quá trình
xử lý chuỗi văn bản.

Hình 2: Chuỗi chuyển đổi trạng thái.
Xem xét chu kỳ hoạt động của M tại trạng thái 4 và ký tự đầu vào hiện tại
là e. Vì g(4, e) = 5 nên máy sẽ nhập trạng thái 5 và chuyển tới ký tự đầu vào tiếp
theo. Kết quả của hàm output(5) cho biết các từ khóa "she" "he" đã được tìm
thấy tại điểm kết thúc của vị trí thứ 4 trong chuỗi văn bản.
Tại trạng thái 5 với ký tự đầu vào r thì máy sẽ tạo ra 2 quá trình chuyển tiếp
trạng thái trong một chu kỳ hoạt động của nó. Vì g(5, r) = fail nên M nhập vào
trạng thái 2 = f(5). Mặt khác, g(2, r) = 8 nên M nhập vào trạng thái 8 và chuyển
tới ký tự đầu vào tiếp theo. Và cuối cùng không có kết quả nào được đưa ra đối
với mỗi chu kỳ hoạt động của máy.
Thuật toán sau sẽ tóm tắt quá trình hoạt động của máy so khớp mẫu
Thuật toán 1: Máy so khớp mẫu.
Đầu vào:
- Chuỗi văn bản x = a1a2…an với mỗi ai là ký tự đầu vào.
- Máy so khớp mẫu M và các hàm goto g, failure f và output đã
được giới thiệu ở trên.

Đầu ra: Vị trí của các từ khóa xuất hiện trong x.
Phương thức:
begin
state = 0;
for i= 1 to n do
begin
while g(state,ai)= fail do state = f(state);
state = g(state,ai);

9


Thuật toán đối sánh mẫu Aho-Corasick
if output(state) != empty then
begin
print i;
print output(state);
end
end
end

Trong thuật toán trên, mỗi vòng lặp for là một chu kỳ hoạt động của máy.
2.2. Xây dựng hàm goto, failure và output
Chúng ta nói rằng ba hàm g, f và output là hợp lệ với một bộ các từ khóa
nếu với các hàm này đưa ra điểm kết thúc từ khóa y tại vị trí i của chuỗi văn bản
x khi và chỉ khi x = uyv và độ dài của uy là i.
Bây giờ chúng ta sẽ xem làm thế nào để xây dựng các hàm goto, failure và
output hợp lệ với một bộ các từ khóa. Quá trình xây dựng gồm có hai phần.
Phần thứ nhất, chúng ta sẽ xác định trạng thái và hàm goto. Phần thứ hai, chúng
ta sẽ tính toán hàm failure. Việc tính toán hàm output được bắt đầu trong phần

một và được hoàn thành trong phần thứ hai.
Để xây dựng hàm goto, chúng ta cần xây dựng một đồ thị goto. Đồ thị bao
gồm một đỉnh đại diện cho trạng thái 0. Sau đó tại trạng thái bắt đầu chúng ta
nhập mỗi từ khóa y bằng cách thêm một đường dẫn trực tiếp vào đồ thị. Các
đỉnh và các nhánh được thêm vào đồ thị tại trạng thái bắt đầu, mỗi đường dẫn
trong đồ thị được gán bằng từ khóa y. Từ khóa y được thêm vào hàm output tại
cuối đường dẫn. Chúng ta thêm các nhánh mới vào đồ thị chỉ khi nào cần thiết.
Ví dụ, giả sử {he, she, his, hers} là một bộ các từ khóa. Việc thêm từ khóa
đầu tiên vào đồ thị, chúng ta được:

Đường dẫn từ trạng thái 0 đến trạng thái 2 sẽ gán từ khóa "he", chúng ta kết
hợp đưa đầu ra "he" tại trạng thái 2. Sau khi thêm từ khóa thứ hai "she", ta được
đồ thị:

10


Thuật toán đối sánh mẫu Aho-Corasick
Đầu ra "she" được đưa ra tại trạng thái 5. Chúng ta thêm từ khóa "his" vào
đồ thị thì có được hình sau. Chú ý rằng khi thêm từ khóa "his" thì trong đồ thị đã
có 1 nhánh từ trạng thái 0 đến trạng thái 1 gãn nhãn h nên chúng ta không cần
thêm một nhánh khác gán nhãn h mà sử dụng luôn nhánh này. Đầu ra "his" sẽ
được đưa ra tại trạng thái 7.

Sau khi thêm từ khóa cuối cùng "hers" vào đồ thị ta có hình sau:

Đầu ra của từ khóa "hers" tại trạng thái 9. Ở đây chúng ta đã sử dụng các
nhánh có sẵn trong đồ thị đó là nhánh từ trạng thái 0 đến trạng thái 1 gán nhãn h
và nhánh từ trạng thái 1 đến trạng thái 2 gán nhãn e.
Tính đến thời điểm này chúng ta đã có cây đồ thị hoàn chỉnh. Để hoàn

thiện việc xây dựng hàm goto, chúng ta thêm một vòng lặp từ trạng thái 0 đến
trạng thái 0 đối với tất cả các ký tự đầu vào khác h và s. Như vậy, chúng ta đã
xây dựng xong một đồ thì có hướng đã được chỉ ra trên hình 1(a). Đồ thị này đại
diện cho hàm goto.
Hàm failure được xây dựng từ hàm goto. Định nghĩa độ sâu của trạng thái s
trong đồ thị goto là độ dài đường dẫn ngắn nhất từ trạng thái bắt đầu tới s. Trong
hình 1(a), trạng thái bắt đầu có độ sâu là 0, trạng thái 1 và 3 là 1, trạng thái 2,4
và 6 là 2,…

11


Thuật toán đối sánh mẫu Aho-Corasick
Chúng ta sẽ tính toán hàm failure cho tất cả các trạng thái có độ sâu là 1, 2,
… và cứ tiếp tục như thế cho đến khi hàm failure tính toán xong cho tất cả các
trạng thái (ngoại trừ trạng thái 0 thì hàm failure không định nghĩa).
Thuật toán để tính toán hàm failure f tại một trạng thái được trình bày khá
đơn giản. Chúng ta đặt f(s) = 0 cho tất cả các trạng thái s có độ sâu là 1. Bây giờ,
giả sử f đã tính toán cho tất cả các trạng thái có độ sâu nhỏ hơn d. Trạng thái có
độ sâu d được xác định từ giá trị nonfail của hàm goto tới trạng thái có độ sâu d
- 1.
Cụ thể, để tính toán hàm failure cho trạng thái có độ sâu d, chúng ta xem
xét một trạng thái r có độ sâu d-1 và thực hiện như sau:
1. Nếu g(r, a) = fail với mọi a, không làm gì cả.
2. Ngược lại, với mỗi một ký tự a sao cho g(r, a) = s chúng ta thực hiện:
a. Gán state = f(r).
b. Thực hiện gán state
f(state) cho đến khi giá trị của state thỏa mãn
g(state, a) fail. (Chú ý rằng do g(0,a) fail với mọi a nên một trạng thái sẽ
luôn luôn được tìm thấy).

c. Gán f(s) = g(state, a).
Ví dụ, để tính toán hàm failure trong hình 1(a), đầu tiên chúng ta gán f(1) =
f(3) = 0 bởi vì trạng thái 1 và 3 đều có độ sâu là 1. Sau đó chúng ta tính toán
hàm failure cho các trạng thái 2,4 và 6 với cùng độ sâu là 2. Để tính toán f(2)
chúng ta gán state = f(1) = 0 vì g(0, e) = 0 nên f(2) = 0. Để tính toán f(6), chúng
ta gán state =f(1) = 0; do g(0, i) = 0 nên f(6) = 0. Để tính toán f(4), ta gán state
= f(3) = 0; vì g(0, h) = 1 nên f(4) = 1. Cứ tiếp tục như thế chúng ta sẽ có được
hàm failure như hình 1(b).
Trong suốt quá trình tính toán chúng ta cũng cập nhập hàm output. Khi xác
định f(s) = s', chúng ta hợp nhất đầu ra của trạng thái s với đầu ra của trạng thái
s'.
Ví dụ, trong hình 1(a) chúng ta xác định được f(5) = 2. Tại điểm này chúng
ta sẽ kết hợp bộ đầu ra của trạng thái 2 là {he} với đầu ra của trạng thái 5 để lấy
được đầu ra mới là {he, she}. Các đầu ra tìm được chúng ta biễu diễn như hình
1(c).
Thuật toán xây dựng hàm goto, failure và output từ tập giá trị K được tóm
tắt như sau:
Thuật toán 2: Xây dựng hàm goto
Đầu vào: Một tập các từ khóa K={
}
Đầu ra: Hàm goto g và một phần hàm output đã được tính toán

12


Thuật toán đối sánh mẫu Aho-Corasick
Phương thức: Chúng ta giả định output(s) là trống khi trạng
thái s được tạo ra lần đầu và g(s,a)= fail nếu a không được
xác định hoặc nếu g(s,a) chưa được định nghĩa. Thủ tục
enter(y) chèn vào trong đồ thị goto một đường dẫn y.

begin
newstate = 0;
for i=1 to k do enter(yi);
for (tất cả a mà g(0,a)=fail)do g(0,a) = 0;
end
procedure enter (a1a2a3…am)
begin
state = 0;
j = 1;
while g(state,aj) != fail do
begin
state = g(state,aj);
j = j + 1;
end
for p=j to m do
begin
newstate = newstate + 1;
g(state, ap) = newstate;
state = newstate;
end
output(state) = {a1a2…am};
end

Thuật toán sau sẽ tính toán hàm failure và thuật toán này có vòng lặp bên
trong giống thuật toán 1.
Thuật toán 3: Xây dựng hàm failure
Đầu vào: Hàm goto g và hàm output từ Thuật toán 2;
Đầu ra: Hàm failure f

và hàm output;


Phương thức:
begin
queue = empty;
for (a mà g(0,a) = s != fail) do
begin
queue = queue + {s};
f(s) = 0;
end
while queue != empty do
begin
đặt r là trạng thái tiếp theo trong queue;
queue = queue – {r};
for (a mà g(0,a) = s != fail) do
begin
queue = queue + {s};
state = f(r);

13


Thuật toán đối sánh mẫu Aho-Corasick
while g(state,a) = fail do
state = f(state);
f(s) = g(state,a);
output(s) = output(s)+ output(f(s));
end
end
end


Vòng lặp for đầu tiên tính toán các trạng thái có độ sâu là 1 và nhập các
trạng thái vào danh sách vào trước – ra trước được ký hiệu bởi biến queue. Vòng
lặp chính while tính toán các trạng thái có độ sâu d từ các trạng thái có độ sâu d1.
Thuật toán 3 tính toán hàm failure không tối ưu trong các trường hợp sau.
Xem xét máy so khớp mẫu ở hình 1, chúng ta có thể nhìn thấy g(4, e) = 5. Nếu
M đang ở trạng thái 4 và ký tự đầu vào hiện tại là a không phải là e, thì M sẽ
nhập trạng thái f(4)=1. Bởi vì M đã xác định được
, nên M sẽ không cần
xem xét giá trị của hàm goto tại trạng thái 1 là e. Thực tế, nếu từ khóa "his"
không được đưa vào thì M có thể trực tiếp chuyển từ trạng thái 4 về trạng thái 0
và bỏ qua quá trình chuyển tiếp trung gian đến trạng thái 1.
Để tránh quá trình chuyển tiếp hàm failure không cần thiết ta có thể sử
dụng f' như sau. Chúng ta gán f'(1) = 0, với i > 1 và f'(i) = f'(f(i)) nếu tất cả các
ký tự đầu vào a thỏa mãn g(f(i), a) fail tức là g(i, a) fail; mặt khác f'(i) = f(i).
Tuy nhiên để tránh việc đánh dấu các quá trình chuyển tiếp failure tại tất cả các
vị trí, ta có thể sử dụng máy trạng thái hữu hạn xác định sử dụng thuật toán 1.
2.3. Đánh giá độ phức tạp của thuật toán
Chúng ta sẽ xem xét độ phức tạp tính toán của thuật toán 1, 2, 3. Phần này
sẽ trình bày cách sử dụng các hàm goto, failure, output và sự thay đổi trạng thái
trong quá trình xử lý chuỗi văn bản độc lập với số lượng các từ khóa. Ngoài ra
chúng ta cũng tìm hiểu làm thế nào để thuật toán 2 và 3 có thể thực hiện trong
thời gian tỉ lệ tuyến tính với tống chiều dài của các từ khóa trong tập K.
Định lý 1: Sử dụng hàm goto, failure, output được xây dựng bởi thuật toán
2, 3; thuật toán 1 tạo ra ít hơn 2n quá trình chuyển tiếp trạng thái trong việc xử
lý một chuỗi văn bản có độ dài n.
Chứng minh: Trong mỗi chu kỳ hoạt động, sau một quá trình chuyển tiếp
của hàm goto thì thuật toán 1sẽ tạo ra 0 hoặc nhiều quá trình chuyển tiếp của
hàm failure. Từ một trạng thái s có độ sâu là d, thuật toán 1 có thể không bao giờ
tạo ra nhiều hơn d quá trình chuyển tiếp failure trong một chu kỳ hoạt động. Bởi
vậy, tổng số lần quá trình chuyển tiếp failure phải ít hơn tổng số lần quá trình

chuyển tiếp goto. Trong quá trình xử lý một chuỗi đầu vào có độ dài n, thuật
toán 1 thực hiện chính xác n quá trình chuyển tiếp goto. Do đó, tổng số lần quá
trình chuyển tiếp trạng thái failure thực hiện phải ít hơn 2n.
14


Thuật toán đối sánh mẫu Aho-Corasick
Độ phức tạp thời gian thực của Thuật toán 1 phụ thuộc vào việc làm thế
nào:
1. Xác định g(s, a) cho mỗi một trạng thái s và ký tự đầu vào a.
2. Xác định f(s) cho mỗi trạng thái s
3. Xác định khi nào output(s) là rỗng
4. Đưa ra output(s).
Chúng ta có thể lưu trữ hàm goto vào mảng 2 chiều, điều này cho phép
chúng ta xác định được giá trị của g(s, a) trong thời gian cụ thể đối với mỗi s và
a. Tuy nhiên, nếu kích thước của bảng chữ cái đầu vào và bộ từ khóa là lớn, thì
việc chỉ lưu trữ những giá trị nonfail trong một danh sách tuyến tính đối với mỗi
trạng thái sẽ mang lại giá trị kinh tế hơn. Ví dụ, để biểu diễn các giá trị này sẽ
làm cho chi phí xác định g(s, a) tỷ lệ với số lượng giá trị nonfail của hàm goto
trong trạng thái s. Một giải pháp hợp lý được đưa ra đó là chúng ta sử dụng các
bảng truy cập trực tiếp để lưu trữ các trạng thái thường xuyên được sử dụng (ví
dụ như trạng thái 0), trạng thái tiếp theo có thể được xác định bằng cách đánh
chỉ số trực tiếp vào bên trong bảng với ký tự đầu vào hiện tại. Sau đó với các
trạng thái thường xuyên được sử dụng chúng ta có thể xác định g(s, a) cho mỗi
a trong một thời gian cụ thể. Các trạng thái của hàm goto ít được dùng và các
trạng thái có một vài giá trị nonfail thì có thể được mã hóa như một danh sách
tuyến tính.
Một phương pháp tiếp cận khác đó là chúng ta sẽ lưu trữ các giá trị goto
với mỗi một trạng thái dưới dạng cây tìm kiếm nhị phân.
Hàm failure có thể được lưu trữ như một mảng một chiều sao cho f(s) có

thể được xác định trong một thời gian cụ thể đối với mỗi trạng thái s.
Bởi vậy, phần không được biểu diễn của thuật toán 1 có thể được bổ sung
để xử lý một chuỗi văn bản có độ dài n trong cn bước, với c là một hằng số
không phụ thuộc vào số các từ khóa.
Bây giờ chúng ta sẽ đi xem xét về thời gian cần thiết để biểu diễn đầu ra.
Chúng ta có thể sử dụng mảng một chiều để xác định giá trị output(s) là rỗng
trong một thời gian cụ thể đối với mỗi trạng thái s. Chi phí cho việc biểu diễn
kết quả đầu ra trong mỗi chu kỳ hoạt động tỷ lệ với tổng các độ dài của các từ
khóa trong output(s) với s là trạng thái mà thuật toán 1 kết thúc chu kỳ vận hành.
Trong nhiều ứng dụng đầu ra output(s) thường chứa một từ khóa, bởi vậy thời
gian cần thiết để biểu diễn kết quả đầu ra tại mỗi vị trí là hằng số.
Tuy nhiên, trong trường hợp một số lượng lớn các từ khóa xuất hiện tại mọi
vị trí của chuỗi văn bản thì thuật toán 1 sẽ mất nhiều thời gian để biểu điễu kết
quả đầu ra. Trong trường hợp xấu nhất, chúng ta có thể phải biểu diễu tất cả các
từ khóa trong K tại hầu hết các vị trí trong chuỗi văn bản. (Xem xét trường hợp
15


Thuật toán đối sánh mẫu Aho-Corasick
sau với
, và chuỗi văn bản là , ở đây kí hiệu cho chuỗi i:
). Tuy nhiên, với bất kỳ thuật toán so khớp mẫu nào chúng ta cũng phải biểu
diễn số lượng các từ khóa tại mỗi một vị trí của chuỗi văn bản là giống nhau. Vì
vậy, khi so sánh các thuật toán so khớp mẫu chúng ta phải so sánh thời gian
thuật toán sử dụng để xác định vị trí từ khóa xuất hiện.
Ngoài ra chúng ta cũng so sánh hiệu suất của thuật toán 1 với thuật toán
xác định tất cả các từ khóa trong K, mà các từ khóa này là chuỗi con của văn
bản đầu vào. Theo thuật toán này, ta có thể lấy lần lượt mỗi từ khóa trong K và
liên lục tìm từ khóa này tại tất cả các vị trí trong chuỗi văn bản. Thời gian thực
hiện thuật toán tỷ lệ thuận với số lượng các từ khóa trong K lần độ dài chuỗi văn

bản. Nếu có nhiều từ khóa, thì hiệu suất của thuật toán này sẽ kém hơn so với
thuật toán 1.
Cuối cùng, chúng ta sẽ xem xét chi phí cho việc tính toán các hàm goto,
failure và output sử dụng thuật thuật toán 2 và 3.
Định lý 2: Thuật toán 2 yêu cầu thời gian tuyến tính tỷ lệ với tổng số độ dài
các từ khóa.
Chứng minh: Tương tự định lý 1.
Định lý 3: Thuật toán 3 có thể được thực hiện trong thời gian tỷ lệ với tổng
số độ dài của các từ khóa.
Chứng minh: Sử dụng các lập luận giống như ở định lý 1, chúng ta có thể
thấy rằng tổng số lần thực thi câu lệnh
được thực hiện trong
thuật toán 3 bị hạn chế bởi tổng các độ dài của các từ khóa. Sử dụng các danh
sách liên kết để hiển thị cho một tập đầu ra của trạng thái, chúng ta có thể thực
thi câu lệnh
trong một thời gian cụ thể. Chú
ý rằng

được phân tách khi câu lệnh được thực thi. Bởi
vậy, thời gian cần thiết để thực hiện thuật toán 3 phụ thuộc vào tổng số độ dài
của các từ khóa.

3. ỨNG DỤNG CỦA THUẬT TOÁN AHO-CORASICK
3.1. Ứng dụng trong các hệ phát hiện xâm nhập (IDS)
Bảo mật đã trở thành vấn đề cấp thiết trong khi sử dụng máy tính. Tin tặc
và những kẻ xâm nhập cố gắng làm giảm các mạng lưới và các dịc vụ web. Để
đảm bảo truyền thông qua internet một số phương pháp được đề suốt như sử
dụng tường lửa, mã hóa và mạng ảo riêng… Bằng phương pháp phát hiện sự
xâm nhập chúng ta có thể tìm thấy các loại tấn công đang thực hiện trên mạng
hoặc máy chủ trên cơ sở thu thập thông tin liên quan đến các cuộc tấn công được

biết đến. Phát hiện sự xâm nhập hệ thống được phân loại như: xâm nhập dựa
trên chữ ký của hệ thống và những bất thường của hệ thống. Những kẻ xâm
16


Thuật toán đối sánh mẫu Aho-Corasick
nhập đã ký kết, như virut máy tính có thể được phát hiện sử dụng phần mềm.
Snort là một mã nguồn mở IDS sẵn sàng cho người sử dụng. NIDS là hệ thống
phát hiện xâm nhập nắm bắt các gói dữ liệu đang di chuyển trên các phương tiện
truyền thông mạng và kết hợp chúng vào một cơ sở dữ liệu chữ ký. Các hệ thống
phát hện sự xâm nhập sử dụng thuật toán tìm kiếm Aho-Corsick tìm thấy tất cả
các lần xuất hiện của mô hình trong một chuỗi văn bản.
3.2. Phát hiện đạo văn
Phát hiện đạo văn là quá trình tìm kiếm đạo văn trong một tác phẩm hoặc
tài liệu. Đạo văn là hành vi sao chép ý tưởng của người khác, đây là một vấn đề
nghiêm trọng đang phải đối mặt trên thế giới hiện nay. Nhiều loại đạo văn đã
được nghiên cứu như: “Copy & Paste plagiarism”, “Word Switch Plagiarism”,
Styte Plagiarism”, “Metaphor Plagiarism”, “Idea Plagiarism”.
3.3. Tin sinh học
Sinh học là khoa học nghiên cứu về sinh học với các phương pháp lưu trữ,
lấy và phân tích dữ liệu sinh học , chẳng hạn như axit nucleic (DNA/RNA) và
trình tự protein , cấu trúc , chức năng và tương tác di truyền. Tin sinh học là
miền công nghệ thông tin và khoa học máy tính kỹ thuật liên quan đến việc giải
quyết các vấn đề sinh học, thường là để giải quyết vấn đề trong trình tự gen .
Một trong những ứng dụng của chuỗi thuật toán kết hợp là xử lý việc tìm kiếm
thông tin trình tự sinh học. Phù hợp gần đúng với một mô hình tìm kiếm trong
chuỗi văn bản là một nhu cầu cơ bản trong phân tử sinh học. Mô hình được gọi
là "truy vấn" và văn bản được gọi là " Cơ sở dữ liệu trình tự " , nhưng chúng tôi
sẽ sử dụng " mô hình" và "văn bản" phù hợp với việc sử dụng trong khoa học
máy tính . Trong khi chuỗi thuật toán chính xác, phù hợp thường được sử dụng

trong khoa học máy tính, thì cũng thường hữu ích trong sinh học. Lý do cho điều
này là sinh học trình tự được thực nghiệm xác định , và có thể bao gồm lỗi.
3.4. Kỹ thuật Forensics
Một chữ ký kỹ thuật số hoặc kỹ thuật số chương trình chữ ký là một
chương trình toán học chứng minh cho tính xác thực của tin nhắn kỹ thuật số
hoặc tài liệu . Một chữ ký số hợp lệ là lý do để người nhận tin rằng thông điệp
được tạo ra bởi một người gửi mà họ đã biết, và rằng nó không bị thay đổi trong
khi quá cảnh. Chữ ký kỹ thuật số thường được sử dụng để phân phối các phần
mềm tài chính giao dịch và trong một số trường hợp khác. Đặc biệt nó có thể
phát hiện được sự giả mạo. Kỹ thuật Forensic tìm kiếm chuỗi văn bản được thiết
kế để tìm kiếm từng byte bằng kỹ thuật số, tại mức vật lý, xác định vị trí các
chuỗi văn bản cụ thể quan tâm đến điều tra. Do tính chất của các tập dữ liệu
thường gặp phải.
17


Thuật toán đối sánh mẫu Aho-Corasick
3.5. Khai thác văn bản
Mục tiêu khai thác dữ liệu tương tự như lưu trữ văn bản đã đề cập đến quá
trình phát sinh thông tin chất lượng cao từ văn bản. Phát sinh trong mô hình dữ
liệu có cấu trúc, vàcuối cùng đánh giá và giải thích các đầu ra.

18


Thuật toán đối sánh mẫu Aho-Corasick

PHẦN III - CÀI ĐẶT CHƯƠNG TRÌNH THỬ NGHIỆM
1. MÔ TẢ CHƯƠNG TRÌNH THỬ NGHIỆM
Chương trình thực thi các thuật toán (Thuật toán 1, Thuật toán 2, Thuật

toán 3) ở trên được cài đặt bằng ngôn ngữ C++ có thể biên dịch và chạy trên
Bloodshed Dev C++ IDE hoặc một trình biên dịch hỗ trợ C++ tương đương.
Toàn bộ chương trình được lưu trong tệp /SOURCE/AhoCorasick.cpp kèm
theo báo cáo này.
Nội dung của chương trình gồm 3 phương thức:
int buildMatchingMachine(const vector<string> &words, char
lowestChar = 'a', char highestChar = 'z')
int findNextState(int currentState, char nextInput, char
lowestChar = 'a')
int main()

Phương thức buildMatchingMachine
Phương thức đảm này nhiệm việc xây dựng máy so khớp mẫu. Tham số
đầu vào của phương thức là một vector dạng chuỗi ký tự chứa tập các từ khóa
(keyword) cần tìm. Ngoài ra, có hai tham số lowestChar và highestChar để giới
hạn tập ký tự của bảng chữ cái được sử dụng trong văn bản cần tìm. Phương
thức này trả về số trạng thái của máy so khớp mẫu.
Các hàm goto g, failure f và output mô tả trong thuật toán được thi công
trong phương thức này.
Phương thức findNextState
Phương thức này đảm nhiệm việc tìm trạng thái tiếp theo trong máy so
khớp mẫu để chuyển giao tác xử lý đến trạng thái đó.
Các tham số của phương thức:
- currentState: Trạng thái hiện tại của máy so khớp, nhận giá trị từ 0 đến
tổng số trạng thái trừ 1.
- nextInput: Ký tự tiếp theo nhập vào máy, giá trị nằm trong khoảng
lowestChar và highestChar.
- lowestChar: Ký tự đầu tiên của bảng chữ cái, tương đương giá trị
lowestChar trong phương thức buildMatchingMachine.
Phương thức main

Đây là phương thức đảm nhận việc vào ra dữ liệu, gọi phương thức
buildMatchingMachine và findNextState để xử lý dữ liệu.
19


Thuật toán đối sánh mẫu Aho-Corasick
Phương thức này nhập một tập các từ khóa trong tệp “keywords.txt”, nhập
chuỗi văn bản cần tìm trong tệp “document.txt”, xử lý dữ liệu và xuất kết quả
ra tệp “output.txt”.
- Tệp keywords.txt là một tệp thuần văn bản, mỗi từ khóa là một đoạn văn
bản chứa trên một dòng.
- Tệp document.txt cũng là một tệp thuần văn bản, nội dung của tệp chứa
chuỗi văn bản đầu vào để tìm các từ khóa xuất hiện trong nó.
- Tệp output.txt chứa thông tin về kết quả tìm kiếm của chương trình.

3. CHẠY THỬ NGHIỆM CHƯƠNG TRÌNH
Để chạy thử nghiệm chương trình có thể thực hiện theo hai cách: Chạy trực
tiếp trên trình Bloodshed Dev C++ IDE bằng việc biên dịch và chạy tệp
AhoCorasick.cpp hoặc chạy tệp đã biên dịch sẵn AhoCorasick.exe. Điều kiện để
chương trình vận hành được là trong cùng thư mục chứa tệp AhoCorasick.cpp
hoặc AhoCorasick.exe phải có hai tệp đầu vào keywords.txt và document.txt.
Sau đây là các bước thực hiện.
Giả sử cả bộ chương trình thử nghiệm được đặt trong thư mục /SOURCE
như sau:

Trong đó:
- Nội dung tệp keywords.txt như sau:
vietnamese
victory
french

became
indochina

- Nội dung tệp document.txt như sau:
20


Thuật toán đối sánh mẫu Aho-Corasick
vietnamvietnamesepronunciationlistenofficiallythesocialistrepu
blicofvietnamaboutthissoundlistenistheeasternmostcountryonthei
ndochinapeninsulainsoutheastasiawithanestimatedmillioninhaviet
namwasachinesecolonyforamillenniumfrombctoadthevietnamesebecam
eindependentfromimperialchinainadfollowingthevietnamesevictory
in

Để chạy chương trình, gọi Command Shell của Windows và chuyển đến
thư mục chứa tệp AhoCorasick.exe.

Chạy tệp AhoCorasick.exe, kết quả xuất ra Console và tệp output.txt.

Có thể xem kết quả trong tệp output.txt.
Searching keywords:
vietnamese

21


Thuật toán đối sánh mẫu Aho-Corasick
victory
french

became
indochina
From text:
vietnamvietnamesepronunciationlistenofficiallythesocialistrepu
blicofvietnamaboutthissoundlistenistheeasternmostcountryonthei
ndochinapeninsulainsoutheastasiawithanestimatedmillioninhaviet
namwasachinesecolonyforamillenniumfrombctoadthevietnamesebecam
eindependentfromimperialchinainadfollowingthevietnamesevictory
in
Results:
- Keyword
- Keyword
- Keyword
- Keyword
- Keyword
- Keyword

"vietnamese" appears from 7 to 16
"indochina" appears from 123 to 131
"vietnamese" appears from 233 to 242
"became" appears from 243 to 248
"vietnamese" appears from 293 to 302
"victory" appears from 303 to 309

Để kiểm thử với các đầu vào khác, chỉ cần thay nội dung trong tệp
keywords.txt và tệp document.txt.
Sau đây là kết quả chạy chương trình với các đầu vào khác nhau:
Lần chạy

Số từ khóa


Độ dài chuỗi văn bản

Thời gian

Lần 1

10

17.500

~ 1 giây

Lần 2

10

50.000

~ 2 giây

Lần 3

10

100.000

~ 3 giây

Lần 4


10

200.000

~ 7 giây

Lần 5

10

200.000

~ 7 giây

Lần 6

10

500.000

~ 15 giây

Lần 7

12

500.000

~ 17 giây


Lần 9

15

500.000

~ 20 giây

Lần 9

18

500.000

~ 25 giây

Lần 10

20

500.000

~ 33 giây

22


Thuật toán đối sánh mẫu Aho-Corasick


4. MỘT VÀI NHẬN XÉT VỀ CHƯƠNG TRÌNH THỬ NGHIỆM
Chương trình thử nghiệm được chúng tôi xây dựng với mục tiêu minh họa
cho phần mô tả thuật toán Aho-Corasick. Mã nguồn của chương trình được tổng
hợp từ Internet ( Trong thực tế, thuật
toán này được tích hợp vào các ứng dụng như Snort (www.snort.org) ở mức tinh
tế và mềm dẻo hơn rất nhiều. Chương trình được viết còn ở mức rất thô sơ và
còn một số hạn chế như:
- Chỉ hỗ trợ các ký tự thuộc bảng chữ cái Tiếng Anh chuẩn, không hỗ trợ
các ký tự đặc biệt.
- Cố định số trạng thái của máy so khớp mẫu (giá trị đang dùng là 6*50+10
= 310), nghĩa là dang giới hạn về số lượng từ khóa và độ dài của từ khóa.
- Chuổi văn bản nhập vào không được chứa các ký tự đặc biệt ngoài các
chữ cái trong bảng ký tự Tiếng Anh. Độ dài của chuỗi văn bản không vượt quá
khả năng lưu trữ của biến kiểu string trong C++ (không vượt quá 2^31 ký tự
trong nền tảng 32 bít).

23


Thuật toán đối sánh mẫu Aho-Corasick

KẾT LUẬN
Như đã thấy rằng thuật toán Aho-Corasick là tương đối tốt với nhiều mô
hình kết hợp và nó có thể được sử dụng trong nhiều lĩnh vực ứng dụng, nhưng
quan sát nó sẽ thấy rằng khi kích thước của máy tự động tăng đáng kể sẽ làm
hiệu suất của thuật toán giảm cả về không gian và thời gian. Những phức tạp của
thuật toán tuyến tính là chiều dài của mô hình cộng với chiều dài của văn bản
tìm kiếm cộng với số lượng các trận đấu đầu ra. Nó được nhìn nhận là rất hấp
dẫn trong số các từ khóa, vì tất cả các từ khóa có thể đồng thời xuất hiện trong
một vượt qua. Aho-Corasick cung cấp giải pháp cho nhiều vấn đề trong thế giới

hiện thực như phát hiện sự xâm nhập, đạo văn, tin sinh học, pháp y kỹ thuật số,
văn bản khai thác và nhiều hơn nữa. Aho-Corsick là một trong nhữngthuật toán
hiệu quả trong khoa học máy tính.
Môn học phân tích và thiết kế thuật toán là môn học rất cơ bản và rất quan
trọng với sinh viên ngành công nghệ thông tin. Thuật toán cùng với cấu trúc dữ
liệu tạo nên chương trình. Việc chọn lựa cấu trúc dữ liệu, việc thiết lập các thuật
toán đúng đắn, có cấu trúc tốt và có hiệu quả là những vấn đề mấu chốt của việc
thiết kế phần mềm. Hai khía cạnh này của việc phát triển phần mềm có tầm quan
trọng như nhau và trong thực tế không thể tách rời nhau, cái này không thể thực
hiện một cách độc lập với cái kia. Qua phần bài tập lớn này đã giúp chúng tôi
hiểu hơn về phương pháp phân tích thiết kế thuật toán và ý nghĩa của nó trong
việc xây dựng phần mềm. Một lần nữa cho phép chúng tôi được cảm ơn thầy
giáo Đào Thanh Tĩnh đã giúp chúng tôi trong suốt thời gian học tập môn học
cũng như giải đáp các thắc mắc, cho tôi một cách nhìn, một phương pháp luận
đúng đắn về phương pháp phân tích thiết kế giải thuật.

24


Thuật toán đối sánh mẫu Aho-Corasick

TÀI LIỆU THAM KHẢO
[1]

Đào Thanh Tĩnh, “Bài giảng môn Phân tích đánh giá thuật toán”.

[2]
Alfred V.Aho and Margaret J.Corasick, “Efficient string matching:
An aid to biblographic search”, Bell Laboratories, 1975.
[3]

Saima Hasib, Mahak Motwani, Amit Saxena, “Importance of AhoCorasick String Matching Algorithm in Real World Applications”, Truba
Institute of Engineering and Information Technology Bhopal (M.P), India, 2013.
[4]
PekkaKilpelainen, “Biosequence Algorithms, Spring2005 – Lecture
4: Set Matchingand Aho-Corasick Algorithm”, University of Kuopio.
[5]
Lubica Benuskova, “Lecture 4: Exact string searching algorithms”,
COSC 348: Computing for Bioinformatics.
[6] Shiri Dori and Gad M. Landau, “Construction of Aho Corasick
Automaton in Linear Time for Integer Alphabets”, University of Haifa and
Polytechnic University.

25


×