字串與文字演算法

精確字串比對問題(exact string-matching problem)

你手上有一大頁文字,想找出某個特定字詞在裡面出現的每一個位置。這就是精確字串比對最日常的面貌:給定一個大字串(稱為文字 text)和一個短字串(稱為模式 pattern),回報文字中每一個讓模式以連續字元區塊形式出現的位置。你的文字編輯器的「尋找」功能、在日誌檔裡搜尋、DNA 資料庫的查找,問的全都是同一個問題。

精確地說:給定長度為 n 的文字 T 和長度為 m 的模式 P,兩者都建立在某個字母表(允許的字元集合,例如 26 個字母,或 DNA 的四個鹼基 A、C、G、T)之上。我們必須輸出每一個位移 s(起始索引),使得文字中那 m 個字元 T[s]、T[s+1]、...、T[s+m-1] 依序恰好等於 P[0]、P[1]、...、P[m-1]。「精確」意指逐字元完全相同——沒有拼錯、沒有萬用字元、沒有空隙。一個這樣的位置稱為一次出現(occurrence)或一次匹配(match)。匹配可能有零次、一次或很多次,而且匹配甚至可以重疊(模式 'aa' 在 'aaa' 中出現在位置 0 和位置 1)。

這是地球上被執行最多次的計算之一,所以慢方法和快方法的差別影響極大。最樸素的做法檢查每一個起始位置,最壞情況下可能花費約 O(n*m);而本領域裡那些巧妙的演算法(Knuth-Morris-Pratt、Z 演算法、Rabin-Karp、Boyer-Moore、Aho-Corasick)藉由永不重新檢查已經弄清楚的字元,把代價壓到 O(n+m),甚至在常見輸入上達到次線性。請把問題的陳述和任何單一演算法分開看:問題是那個提問,而有許多演算法以不同的取捨來回答它。

文字 T = "abracadabra"(n=11),模式 P = "abra"(m=4)。出現位置在位移 0(abra...)和位移 7(...abra),所以答案是集合 {0, 7}。模式 "cad" 只出現在位移 4;模式 "xyz" 哪裡都不出現,所以答案是空集合。

輸出是起始位置的集合;匹配可以重疊,而這個集合也可能是空的。

一開始就要決定你要的是所有出現位置還是只要第一個,以及重疊匹配算不算——這些會同時改變預期輸出和適合的演算法。也要確定比對是否區分大小寫;那屬於問題的定義,而不是演算法的一部分。

又稱
string searchingsubstring searchpattern matching子字串搜尋模式比對