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ìmkiếm, trong đó mẫu P được xem như khoá, tuy nhiên các thuật toán tìm kiếmthông thường không áp dụng được một cách
Trang 1
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
Trang 2LỜ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ếtsứ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ánhchuỗ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ănbả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ìmkiếm, trong đó mẫu P được xem như khoá, tuy nhiên các thuật toán tìm kiếmthô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), Karp-Rabin (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 Corasick (AC), một thuật toán được cho là tương đối hiệu quả và đang được ứngdụ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ợpthông tin cũng như thi công chương trình minh họa Nhưng do thời gian và kinhnghiệ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ấtmong 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ụchoàn thiện nội dung nghiên cứu
Trang 3Aho-MỤC LỤC
LỜI NÓI ĐẦU 0
MỤC LỤC 2
PHẦN I - KHÁI NIỆM CƠ BẢN VỀ ĐỐI SÁNH CHUỖI KÝ TỰ 3
1 GIỚI THIỆU 3
2 BÀI TOÁN ĐỐI SÁNH MẪU 3
3 MỘT SỐ THUẬT TOÁN ĐỐI SÁNH MẪU 4
3.1 Thuật toán Brute Force 4
3.2 Thuật toán Knuth-Morris-Pratt 4
3.3 Thuật toán automat hữu hạn 4
3.4 Thuật toán Boyer-Moore 4
3.5 Thuật toán Karp-Rabin 5
3.6 Các thuật toán khác 5
PHẦN II - THUẬT TOÁN AHO-CORASICK 6
1 GIỚI THIỆU VỀ THUẬT TOÁN 6
2 PHÂN TÍCH THUẬT TOÁN 6
2.1 Máy tìm kiếm mẫu 6
2.2 Xây dựng hàm goto, failure và output 9
2.3 Đánh giá độ phức tạp của thuật toán 13
3 ỨNG DỤNG CỦA THUẬT TOÁN AHO-CORASICK 15
3.1 Ứng dụng trong các hệ phát hiện xâm nhập (IDS) 15
3.2 Phát hiện đạo văn 16
3.3 Tin sinh học 16
3.4 Kỹ thuật Forensics 16
3.5 Khai thác văn bản 17
PHẦN III - CÀI ĐẶT CHƯƠNG TRÌNH THỬ NGHIỆM 18
1 MÔ TẢ CHƯƠNG TRÌNH THỬ NGHIỆM 18
3 CHẠY THỬ NGHIỆM CHƯƠNG TRÌNH 19
4 MỘT VÀI NHẬN XÉT VỀ CHƯƠNG TRÌNH THỬ NGHIỆM 21
KẾT LUẬN 22
TÀI LIỆU THAM KHẢO 23
Trang 4PHẦ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 trongviệ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à đốisánh chuỗi ký tự (String Matching) Bài toán đặt ra như sau “Cho trước mộtchuỗ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ủamẫ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ìmkiếm, trong đó mẫu P được xem như khoá, tuy nhiên các thuật toán tìm kiếmthô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ệ.
Trang 53 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ịchmẫu sang phải một ký tự cho đến khi kiểm tra hết văn bản Thuật toán BruteForce không cần giai đoạn tiền xử lý cũng như các mảng phụ cho quá trình tìmkiế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ếntí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ợidụng lại những thông tin của lần thử trước cho lần sau Trong thuật toán BruteForce 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 sosá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ồilư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ủamẫ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ả trongthự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ácchươ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 sangtrá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)
Trang 6Trong 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ầnsau
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ờigian 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àitoá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 đâymộ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 sosá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ồmnhữ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áisang phải
- Thuật toán Colussi và Galil-Giancarlo lại chia mẫu thành hai tập và tiếnhà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ựavà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ếnhà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ậttoán sánh mẫu văn bản Wu-Manbers (ký hiệu là WM) được Sun Wu và UdiManber công bố vào năm 1994 [WM94] Các tác giả sử dụng các ý tưởng nhảycủa thuật toán BM do R S Boyer và J S Moore [BM77] và hàm băm
Trang 7PHẦ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ởiAlfred V Aho and Margaret J Corasick Đây là một thuật toán đơn giản và hiệuquả đượ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 trongchuỗ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ựngmá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ôngmớ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âydự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àyphả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ớpmẫ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ạnchế 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ữuhạn Phương pháp tiếp cận ở đây là sự kết hợp ý tưởng trong thuật toán Knuth-Morris-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 địnhcá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ựngmá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.
Trang 8Hì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 sokhớ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ự
Trang 9đầ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êncủ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ằngcá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.
Trang 10if 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ầnmộ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ị baogồ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ị:
Trang 11Đầ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ànthiệ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 đếntrạ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 đạidiệ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,…
Trang 12Chú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áctrạ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ómtắ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