專利名稱:基于基數(shù)排序的字符串后綴數(shù)組構(gòu)造方法
技術(shù)領(lǐng)域:
本發(fā)明涉及一種字符串后綴數(shù)組構(gòu)造方法,尤其涉及一種通過計算機在線性時間 內(nèi)利用基數(shù)排序自動完成字符串后綴數(shù)組構(gòu)造的方法。
背景技術(shù):
字符串后綴數(shù)組是后綴樹的一個節(jié)省空間的替代型數(shù)據(jù)結(jié)構(gòu),最先由Manber和 Myers在文獻1,2中提出,可以在更小的空間內(nèi)實現(xiàn)等同后綴樹的算法。后綴數(shù)組在數(shù)據(jù) 索引和模式匹配等應(yīng)用中有廣泛用途。本文發(fā)明了一個新的后綴數(shù)組構(gòu)造算法,利用基數(shù) 排序和“切分-合并”方法在線性時間內(nèi)為任意給定的字符串構(gòu)造其后綴數(shù)組。在本文的陳述中用到以下術(shù)語字符集一個字符集Σ是一個建立了全序關(guān)系的集合,即Σ中任意兩個不同的元素 α和β都可以比較大小,要么α < β,要么α > β。字符集Σ中的元素稱為字符,其中 最小的字符為‘$’。本文所涉及的字符集大小假設(shè)為一個常數(shù)0(1)。字符串一個長度為η的字符串S是將η個屬于字符集Σ中的字符按其位置依次排 列形成的數(shù)組s
,S的結(jié)束符固定為‘$’,并且‘$’不在S中的其它位置出現(xiàn)。子串字符串S的子串S[i. . j], i ^ j,表示S串中從位置i到位置j的一段字符 串,也就是由字符s[i],S[i+1],. . .,S[j]組成的字符串。后綴字符串S的一個后綴是指從某個位置i開始到結(jié)束符$的一個子串。從第i 個字符開始的后綴表示為suf (S,i),也就是suf (S,i) = S[i..n_l]。字符和后綴類型S中的字符分為L和S兩種類型1) ‘$,為 S 類型;2)S[i],i e [1,n-1]為 S 類型,當(dāng)且僅當(dāng) suf(S,i) < suf (S, i+1),即 S[i] < S[i+1]或者 S[i] = S[i+1]且 S[i+1]為 S 型。3)S[i],i e [1,n-1]為 L 類型,當(dāng)且僅當(dāng) suf (S, i) > suf (S, i+Ι),即 S[i] > S[i+1]或者 S[i] = S[i+1]且 S[i+1]為 L 型·’4)后綴suf (S,i)是S類型當(dāng)且僅當(dāng)字符S[i]為S類型;后綴suf (S,i)是L類 型當(dāng)且僅當(dāng)字符S[i]為L類型。LMSdeftmost S-type,最左S類型)字符和后綴1) ‘$’為 LMS 字符;2)S[i],i e [l,n-l]為LMS字符,當(dāng)且僅當(dāng)S[i]為S類型且S[i_l]為L類型;3)后綴suf (S,i)是LMS后綴當(dāng)且僅當(dāng)字符S [i]為LMS字符。LMS 子串1) ‘$’為 LMS 子串;2)S[i.. j]為LMS子串,當(dāng)且僅當(dāng)1≤i < j <n,S[i]禾Π S[j]同為LMS字符,且 S[i]和S[j]之間不存在其他LMS字符。指針數(shù)組指針數(shù)組Pl記錄字符串S中所有LMS子串的首字母所在的位置,即Pl [i]記錄字符串S中(從左到右)第i+Ι個LMS子串的首字母在S中的位置。字符串大小比較兩個字符串的大小比較,是指通常所說的“字典順序”比較,亦即 對于兩個字符串u和V,令i從0開始順次比較u[i]和v[i]。如果u[i] = v[i]則令i加 1再繼續(xù)比較下一個u[i]和v[i],否則若u[i] <v[i]則認為u<v,或者u[i] >v[i]則
認為U > Vo后綴數(shù)組S的后綴數(shù)組SA是一個包含η個整數(shù)的一維數(shù)組,對于i e
滿 足SUf (S,SA [i]) <suf(S,SA[i+l])。也就是將S的η個后綴從小到大進行排序之后把排 好序的各后綴首字母在S中的位置從左到右順次放入SA中。d-字符字符串S中的字符S[i]是d-字符,d彡2,當(dāng)且僅當(dāng)滿足以下條件l)S[i]是一個LMS字符;或者2)S[i_d]是d-字符,S[i+1]不是LMS字符,并且子串S[i-d+l..i_l]內(nèi)沒有d_字符。d-子串對S中的每個d-字符S[i],d彡2和i <n-d_l,子串S[i. . i+d+1]稱為 一個 d-子串。如果 i 彡 η-d-l,則 S[i. . i+d+1] = 5[土..11-2]{5[11-1]}(1+1-(11-24),其中 {S [η-1]} χ表示把字符S [η-1]重復(fù)χ次所構(gòu)成的字符串。指針數(shù)組指針數(shù)組Pl記錄字符串S中所有d-子串的首字母所在的位置,即Pl [i] 記錄字符串S中(從左到右)第i+Ι個d-子串的首字母在S中的位置。加權(quán)字符字符串S中的字符S[i]的加權(quán)字符定義為Sw[i] = 2S[i]+t[i]。d-加權(quán)子串字符串S中的d-子串S[i.. j]的加權(quán)子串定義為Sv[i.. j] = S[i.. j-l]Sw[j]0利用以上術(shù)語,我們給出一個構(gòu)造字符串后綴數(shù)組的例子如下。字符串 S = baac$,其長度 η = 5,suf (S,0) = baac$, suf (S, 1) = aac$, suf (S, 2) = ac$, suf (S, 3) = c$, suf (S, 4) = $。根據(jù)字符串大小比較的定義容易知道suf (S, 4) < suf (S, 1) < suf (S,2) < suf (S, 0) < suf (S,3)。再根據(jù)后綴數(shù)組的定義,容易得出 SA
= 4,SA[1] = 1,SA[2] = 2,SA[3] = 0,SA[4] = 3,即 SA = [4,1,2,0,3]。現(xiàn)存有多種構(gòu)造字符串后綴數(shù)組的計算機算法,參見文獻1-8。按這些算法的時 間復(fù)雜度來分類,可以分為線性時間或超線性時間兩大類。其中線性時間算法的定義為給 定一個字符集Σ上長度為η的字符串,即該字符串包含η個屬于字符集Σ中的字符,對該字 符串中η個后綴進行排序的時間復(fù)雜度為Ο(η)?,F(xiàn)存的線性時間后綴數(shù)組構(gòu)造算法存在實 際運行速度慢、空間復(fù)雜度大的缺點3,4,5,7,8,限制了它們在實踐中的運用。參考文獻1、U.Manber and G. Myers, "Suffix arrays :A new method for online string searches,,,in Proceedings of SODA, 1990, pp. 319-327.2、U. Manber and G. Myers, "Suffix arrays :A new method for on-line string searches,,,SIAM Journal on Computing, vol. 22, no. 5, pp. 935-948,1993.3>D. K. Kim, J. S. Sim, H. Park, and K. Park,"Linear-time construction of suffix arrays, "in Proceedings of CPM,2003, pp.186-199.4、P. Ko and S. Aluru,"Space-efficient linear time construction of suffix arrays, "Journal of Discrete Algorithms, vol. 3,no.2-4,pp.143-156,2005.
5> J. Karkkainen, P. Sanders, and S. Burkhardt, "Linear work suffix array construction,,,JACM, no. 6,pp. 918-936,Nov. 2006.6、G. Manzini and P. Ferragina, "Engineering a lightweight suffix array construction algorithm,,,Algorithmica, vol. 40, no. 1, pp. 33-50, Sep. 2004.7> S. J. Puglisi, W. F. Smyth, and A. H. Turpin, "A taxonomy of suffix arrayconstruction algorithms,,,ACM Comput. Surv. , vol. 39, no. 2, pp. 1-31, 2007.8> S. J. Puglisi, W.F. Smyth, and A. Turpin, "The performance of linear time suffix sorting algorithms," in Proceedings of Data Compression Conference, Mar. 2005,pp. 358-3670
發(fā)明內(nèi)容
針對以上的不足,本發(fā)明提供了一種新型的線性時間的基于基數(shù)排序的字符串后 綴數(shù)組構(gòu)造方法SA-DS),可以有效克服現(xiàn)存線性時間后綴數(shù)組構(gòu)造方法的缺點。它包括1)標(biāo)記字符串中每個字符和后綴的類型,從右向左掃描一遍字符串S,按照后綴 類型的定義比較當(dāng)前掃描的兩個相鄰字符s[i]和S[i+1],得出每一個字符和后綴的類型, 用數(shù)組t來記錄;2)從左向右掃描一遍數(shù)組t,找出所有d-字符出現(xiàn)的位置,從而獲取所有d-子串 的首字母指針,用Pl來記錄每一個d-子串的指針;3)通過d-子串指針數(shù)組P1、數(shù)組B和SA來對S中所有的d_加權(quán)子串進行基數(shù) 排序;4)根據(jù)幻排序的結(jié)果重新命名字符串S中的各個d-加權(quán)子串,形成一個縮短了 的新串Sl ;5)如果Sl的每個字符都是唯一的,則直接排序Sl的各后綴來計算Sl的后綴數(shù)組 SAl,否則以Sl和SAl作為輸入?yún)?shù)遞歸調(diào)用SA-IS算法,即SA-DS (Si,SAl);6)根據(jù)5)中獲得的Sl的后綴數(shù)組SAl歸納計算S的后綴數(shù)組SA ;7)返回。所述步驟幻中對S中所有d-加權(quán)子串進行基數(shù)排序的過程包括31)對所有d-加權(quán)子串的最后一個字符進行兩輪基數(shù)排序先根據(jù)每個字符的類 型進行基數(shù)排序,然后再根據(jù)每個字符的大小進行基數(shù)排序;32)在步驟31)的排序結(jié)果上,繼續(xù)對所有d-加權(quán)子串根據(jù)它們的前d+Ι個字符 進行基數(shù)排序從每個d-加權(quán)子串的倒數(shù)第二個字符開始到第一個字符結(jié)束,每輪根據(jù)一 個字符排序,總共排d+Ι輪。所述步驟4)中計算新字符串Sl的步驟包括41)從左向右掃描SA數(shù)組中已排序的所有d-加權(quán)子串,依次比較相鄰的兩個 d-加權(quán)子串的大小,被比較的d-加權(quán)子串從0開始編號命名,如果兩個d-加權(quán)子串相等, 則編號一樣,否則后者編號等于前者的編號加1 ;42)把S中各個d-加權(quán)子串用其在步驟41)中獲取的編號來代替,所形成的新字 符串即為Si。所述步驟6)中從SAl歸納計算SA的過程如下
61)初始化SA的所有元素為-1,找出S中所有后綴在SA中所屬各桶的結(jié)束位置, 從右向左掃描SAl數(shù)組,對每個掃描到的元素SAl [i],如果suf (S,Pl [SAl [i]])是LMS后 綴,則把Pl [SAl [i]]放在后綴suf (S,Pl [SAl [i]])在SA中所屬桶的當(dāng)前結(jié)束位置,然后再 把該桶的結(jié)束位置向左移動一格;62)找出S中所有后綴在SA中所屬各桶的起始位置,從左向右掃描SA數(shù)組,對于 掃描到的每個不為"I的元素SA[i],如果S[SA[i]-l]是L型,則把SA[i]-l這個數(shù)值填入 suf (S, SA[i]-l)這個后綴在SA中所屬桶的當(dāng)前起始位置,然后再把該桶的起始位置向右 移動一格;63)找出S中所有后綴在SA中所屬各桶的結(jié)束位置,從右向左掃描SA數(shù)組,對 于掃描到的每個元素SA[i],如果S[SA[i]-l]是S型,則把SA[i]-l這個數(shù)值填入suf (S, SA[i]-l)這個后綴在SA中所屬桶的當(dāng)前結(jié)束位置,然后再把該桶的結(jié)束位置向左移動一 格,其中,把字符串S的所有后綴按其第一個字符在數(shù)組SA中進行排序,則所有第一 個字符相同的后綴都連續(xù)排列在SA中的某一段區(qū)域,這段區(qū)域我們稱之為對應(yīng)這些后綴 的一個桶。本發(fā)明的有益效果本發(fā)明的基于基數(shù)排序的字符串后綴數(shù)組構(gòu)造方法可以在線 性時間O(n)內(nèi)對長度為η的字符串構(gòu)造其后綴數(shù)組,相比現(xiàn)存的其他線性時間后綴數(shù)組構(gòu) 造方法,本發(fā)明的方法具有運行速度快、耗用空間小、容易實現(xiàn)的優(yōu)點。
圖1為本發(fā)明基于基數(shù)排序的字符串后綴數(shù)組構(gòu)造方法的流程圖。
具體實施例方式下面結(jié)合附圖對本發(fā)明進行進一步闡述。如圖1所示,本發(fā)明的基于基數(shù)排序的字符串后綴數(shù)組構(gòu)造方法的流程圖中各步 驟的偽代碼給出如下,其中每個數(shù)組的元素以從左到右的方式存儲,即第一個元素在最左 邊,最后一個元素在最右邊。根據(jù)d-子串的定義,我們知道每個d-子串的長度都是固定為d+2個字符,其中 d ^ 2,因此,對S中所有定長d-子串進行排序時可以利用簡單快速的基數(shù)排序算法。相比 其他線性時間后綴數(shù)組構(gòu)造算法,這個特點是本發(fā)明方法的一個獨特優(yōu)點。SA-IS (S, SA)S 輸入字符串;(長度為η個字符,包含nl個d-子串)SA =S的后綴數(shù)組;Sl 整型數(shù)組;(記錄對S中各d-子串重命名后形成的新字符串,長度為nl)SAl =Sl的后綴數(shù)組t 布爾數(shù)組;(記錄S中每個字符的類型,長度為η)Pl 整型數(shù)組;(記錄S中各d-子串出現(xiàn)的位置,長度為nl)B:整型數(shù)組;(排序時用到的輔助數(shù)組,長度為Μ Σ (S) I I (即字符集Σ中元素的 個數(shù)))
1)標(biāo)記字符串中每個字符和后綴的類型。從右向左掃描一遍字符串S,按照后綴 類型的定義比較當(dāng)前掃描的兩個相鄰字符s[i]和S[i+1],得出每一個字符和后綴的類型, 用數(shù)組t來記錄;2)從左向右掃描一遍數(shù)組t,找出所有d-字符出現(xiàn)的位置,從而獲取所有d-子串 的首字母指針,用Pl來記錄每一個d-子串的指針;3)通過d-子串指針數(shù)組P1、數(shù)組B和SA來對S中所有的d_加權(quán)子串進行基數(shù) 排序;4)根據(jù)步驟幻排序的結(jié)果重新命名字符串S中的各個d-加權(quán)子串,形成一個縮 短了的新串Si;5)如果Sl的每個字符都是唯一的,則直接排序Sl的各后綴來計算Sl的后綴數(shù)組 SAl,否則以Sl和SAl作為輸入?yún)?shù)遞歸調(diào)用SA-IS算法,即SA-DS (Si,SAl);6)根據(jù)步驟5)中獲得的Sl的后綴數(shù)組SAl歸納計算S的后綴數(shù)組SA ;7)返回。下面對上述步驟!3)、4)h和6)的細節(jié)進行進一步描述,為方便敘述,首先引入一個 概念“桶”,把字符串S的所有后綴按其第一個字符在數(shù)組SA中進行排序,則所有第一個字 符相同的后綴都連續(xù)排列在SA中的某一段區(qū)域,這段區(qū)域我們稱之為對應(yīng)這些后綴的一 個桶。如果S中包含有m個不同的字符,則SA中會形成m個桶,每個桶中所包含的后綴的 首字符都相同。如果一個桶所包含的后綴的首字符為‘y’,我們也簡稱該桶為字符 桶。 另外,當(dāng)我們說把一個后綴放入SA中的一個單元,其含義是在SA中該單元記錄此后綴在S 中的位置。步驟幻中對S中所有d-加權(quán)子串進行基數(shù)排序的步驟如下31)對所有d-加權(quán)子串的最后一個字符進行兩輪基數(shù)排序(1)先根據(jù)每個字符 的類型進行基數(shù)排序;(2)然后再根據(jù)每個字符的大小進行基數(shù)排序;32)在步驟31的排序結(jié)果上,繼續(xù)對所有d-加權(quán)子串根據(jù)它們的前d+Ι個字符進 行基數(shù)排序從每個d-加權(quán)子串的倒數(shù)第二個字符開始到第一個字符結(jié)束,每輪根據(jù)一個 字符排序,總共排d+Ι輪。步驟4)中計算新字符串Sl的步驟如下41)從左向右掃描SA數(shù)組中已排序的所有d-加權(quán)子串,依次比較相鄰的兩個 d-加權(quán)子串的大小,被比較的d-加權(quán)子串從0開始編號命名,如果兩個d-加權(quán)子串相等, 則編號一樣,否則后者編號等于前者的編號加1。42)把S中各個d-加權(quán)子串用其在步驟41)中獲取的編號來代替,所形成的新字 符串即為Si。步驟6)中從SAl歸納計算SA的流程如下61)初始化SA的所有元素為-1,找出S中所有后綴在SA中所屬各桶的結(jié)束位置, 從右向左掃描SAl數(shù)組,對每個掃描到的元素SAl [i],如果suf (S,Pl [SAl [i]])是LMS后 綴,則把Pl [SAl [i]]放在后綴suf (S,Pl [SAl [i]])在SA中所屬桶的當(dāng)前結(jié)束位置,然后再 把該桶的結(jié)束位置向左移動一格。62)找出S中所有后綴在SA中所屬各桶的起始位置,從左向右掃描SA數(shù)組,對于 掃描到的每個不為—I的元素SA[i],如果S[SA[i]-l]是L型,則把SA[i]-l這個數(shù)值填入
8Suf(S,SA[i黨1)這個后綴在SA中所屬桶的當(dāng)前起始位置,然后再把該桶的起始位置向右移動一格。
63)找出S中所有后綴在SA中所屬各桶的結(jié)束位置,從右向左掃描SA數(shù)組,對于掃描到的每個元素SA[i],如果SLSA[i黨1]是S型,則把SA[i黨l這個數(shù)值填入Suf(S,SA[i黨1)這個后綴在SA中所屬桶的當(dāng)前結(jié)束位置,然后再把該桶的結(jié)束位置向左移動一格。
下面我們以字符串“mmiiSSiiSSiippii$”和d一2為例,給出SA—DS算法從S計算其后綴數(shù)組SA的詳細過程,以幫助理解本發(fā)明的細節(jié)。首先給出各步運算結(jié)果如下
遞歸層次o
注釋掃描S計算數(shù)組t和Pl
l
ol索弓!o l 2 3 4 5 6 7 8 9 o l 2 3 4 5 6
02 Sm m i i S S i i S S i i p p i i$
03 to o l l o o l l o o l l o o o o l
04 Pl2 4 6 8 l o 12 14 16
注釋對Pl中的d一加權(quán)子串進行基數(shù)排序和命名以產(chǎn)生Sl
05第l輪14 16 12 4 8 lo 2 6
06第2輪14 16 12 4 8 lo 2 6
07第3輪16 14 lo 2 6 12 4 8
08第4輪16 14 lo 2 6 12 4 8
05] 09 Sl3 5 3 5 2 4 l o
遞歸層次l
注釋掃描S計算數(shù)組t和Pl
lo索弓!o l 2 3 4 5 6 7
09] l l S3 5 3 5 2 4 l o
]0]12tl o l o l o o l
]]]13Pl2 4 7
注釋對Pl中的d一加權(quán)子串進行基數(shù)排序和命名以產(chǎn)生Sl
14第l輪4 7 2
15第2輪7 4 2
16第3輪7 4 2
17第4輪7 4 2
18Sl 2 l o
19SAl2 l o
遞歸結(jié)束,開始回溯
遞歸層次l
注釋從SAl歸納排序出SA
20索弓!o l 2 3 4 5 6 7
2l SAl2 l o
22 第 1 步7 -1 4 -1 2 -1-1-1
23 第 2 步7 6 4 -1 2 531
對第3步7 64 20 531
遞歸層次0
注釋從SAl歸納排序出SA
1
25 索引0123456 7 89 0 12 34 5 6
26 SAl 7 6 4 2 053 1
27 第 1 步16 -1 -1 -1 -1-110 6 2-1 -1 -1-1 -1-1 -1 -1
沘第 2 步16 15 14 -1 -1-110 6 21 0 1312 95 8 4
四第 3 步16 15 14 10 621 1 73 10 1312 95 8 4
以上各步驟說明如下。
1)標(biāo)記字符串中每個字符類型。首先‘$’是S型,然后從右向左掃描一遍字符串S,按照后綴類型的定義比較當(dāng)前掃描的字符S[i]和它的后繼字符S[i+1],得出字符S[i]
的類型,若 S[i] >S[i+l],則 S[i]為 L 型,t[i] =0;若 S[i] <S[i+l],則 S[i]為 S 型, t[i] = 1 ;若 S[i] = S[i+1],S[i]和 S[i+1]的類型相同,即 t[i] = t[i+l],獲取的 t 在 第3行給出。2)求出S中各d-子串位置。從左往右掃描字符類型數(shù)組t,標(biāo)記出各個d-子串 位置,并按它們在S中的位置從左到右依次記錄在第4行的數(shù)組Pl中。對應(yīng)的d-子串為 Uiss (2),ssii (4),iiss (6),ssii (8),iipp (10),ppii (12),ii$ (14),$ (16)},其中每個子 串后面小括號里的數(shù)字是該子串在S中的位置,由于此例子假設(shè)d = 2,故每個d-子串的長 度固定為d+2 = 4個字符。3)通過d-子串指針數(shù)組P1、數(shù)組B和SA來把所有d-加權(quán)子串進行基數(shù)排序。第 1輪根據(jù)各d-加權(quán)子串的最后一個字符排序,結(jié)果在第5行給出。之后3輪繼續(xù)根據(jù)d-加 權(quán)子串的前3個字符排序,依次得到的排序結(jié)果在第6-8行給出。根據(jù)第8行的結(jié)果,所 有 d-加權(quán)子串從小到大排序為{$ (16),ii$ (14),iipp (10),iiss ⑵,iiss (6),ppii (12), ssii(4),ssii (8)}。4)對已排序的d-加權(quán)子串進行編號命名,可得結(jié)果為{0,1,2,3,3,4,5,5}。再把 S中各d-子串用他們的編號代替,得到在第9行給出的新字符串Sl= [3,5,3,5,2,4,1,0]。5)由于Sl中有相同的字符,故以Sl和SAl為參數(shù)遞歸調(diào)用SA-DS (Si,SAl),進入 遞歸層次1。在第18行,由于Sl中的字符各不相同,故直接排序Sl的各后綴,在第19行得 到Sl的后綴數(shù)組SAl。6)第20-M行是在遞歸層次1上從SAl歸納排序出SA。此層次上的S為遞歸層 次0上的Si,即第9行給出的Sl ;而此層次上的Pl在第13行給出,SAl在19行給出。換 言之,在此遞歸層次有 S= [3,5,3,5,2,4,1,0], Pl = [2,4,7], SAl = [2,1,0]。1)在第21行先初始化SA的所有元素為-1。然后找出各后綴桶的結(jié)束位置,再從 右向左掃描SA1。因為SA1[2] =0,則查看P1
的值為2,由于S [2]是LMS字符,則把位 置2放入后綴suf (S,2)在SA中所屬桶的當(dāng)前結(jié)束位置,此處為SA[4],并把該桶的結(jié)束位 置向左移一格。完成掃描SAl后,S的所有LMS子串都放在其所屬桶的末端,如第22行所示。2)在第23行先找出S中所有后綴在SA中所屬各桶的起始位置,然后從左向右掃 描SA數(shù)組。因為SA
= 7,并且S [7-1]是L型,則把7_1 = 6這個數(shù)值填入后綴suf (S, 6)在SA中所屬桶的當(dāng)前起始位置,此處為SA[1],然后再把這個桶的起始位置向右移動一 格。掃描到SA[1] =6時,因為S[6-1]是L型,則把6-1 = 5這個數(shù)值填入后綴suf (S,5) 在SA中所屬桶的當(dāng)前起始位置,此處為SA[5],然后再把這個桶的起始位置向右移動一格。 掃描到SA[3] =-1時,跳過。繼續(xù)掃描到SA[5] =5時,因為S[5-l]不是L型,也跳過。如 此完成掃描SAl后,S的所有L類型的后綴都放在SA內(nèi)其所屬桶的前端,第23行所示。3)在第對行先找出S中所有后綴在SA中所屬各桶的結(jié)束位置,然后從右向左掃 描SA數(shù)組。因為SA[7] = 1,并且S[l-1]是S型,則把1-1 = 0這個數(shù)值填入后綴suf (S, 0)在SA中所屬桶的當(dāng)前結(jié)束位置,此處為SAW],然后再把這個桶的結(jié)束位置向左移動一 格。掃描到SAW] =3時,因為S [3-1]是S型,則把3-1 = 2這個數(shù)值填入后綴suf (S,2) 在SA中所屬桶的當(dāng)前結(jié)束位置,此處為SA[3],然后再把這個桶的結(jié)束位置向左移動一格。 繼續(xù)掃描到SA[2] =4時,因為S[4-l]不是S型,則跳過。如此完成掃描SAl后,S的所有 后綴都放在各自所屬桶,如第對行所示。第25- 行是在遞歸層次0上從SAl歸納排序出SA,其運算過程與第20- 行類 似。第四行是最后輸出的后綴數(shù)組。以上所述僅為本發(fā)明的較佳實施方式,本發(fā)明并不局限于上述實施方式,在實施 過程中可能存在局部微小的結(jié)構(gòu)改動,如果對本發(fā)明的各種改動或變型不脫離本發(fā)明的精 神和范圍,且屬于本發(fā)明的權(quán)利要求和等同技術(shù)范圍之內(nèi),則本發(fā)明也意圖包含這些改動 和變型。
權(quán)利要求
1.一種基于基數(shù)排序的字符串后綴數(shù)組構(gòu)造方法,其特征在于,它包括1)標(biāo)記字符串中每個字符和后綴的類型,從右向左掃描一遍字符串S,按照后綴類型的 定義比較當(dāng)前掃描的兩個相鄰字符s[i]和S[i+1],得出每一個字符和后綴的類型,用數(shù) 組t來記錄;2)從左向右掃描一遍數(shù)組t,找出所有d-字符出現(xiàn)的位置,從而獲取所有d-子串的首 字母指針,用Pl來記錄每一個d-子串的指針;3)通過d-子串指針數(shù)組Pl、數(shù)組B和SA來對S中所有的d-加權(quán)子串進行基數(shù)排序;4)根據(jù)3)排序的結(jié)果重新命名字符串S中的各個d-加權(quán)子串,形成一個縮短了的新 串Sl ;5)如果Sl的每個字符都是唯一的,則直接排序Sl的各后綴來計算Sl的后綴數(shù)組SA1, 否則以Sl和SAl作為輸入?yún)?shù)遞歸調(diào)用SA-IS算法,即SA-DS (Si,SAl);6)根據(jù)5)中獲得的Sl的后綴數(shù)組SAl歸納計算S的后綴數(shù)組SA;7)返回。
2.根據(jù)權(quán)利要求1所述的基于基數(shù)排序的字符串后綴數(shù)組構(gòu)造方法,其特征在于,所 述步驟3)中對S中所有d-加權(quán)子串進行基數(shù)排序的過程包括31)對所有d-加權(quán)子串的最后一個字符進行兩輪基數(shù)排序先根據(jù)每個字符的類型進 行基數(shù)排序,然后再根據(jù)每個字符的大小進行基數(shù)排序;32)在步驟31)的排序結(jié)果上,繼續(xù)對所有d-加權(quán)子串根據(jù)它們的前d+Ι個字符進行 基數(shù)排序從每個d-加權(quán)子串的倒數(shù)第二個字符開始到第一個字符結(jié)束,每輪根據(jù)一個字 符排序,總共排d+Ι輪。
3.根據(jù)權(quán)利要求2所述的基于基數(shù)排序的字符串后綴數(shù)組構(gòu)造方法,其特征在于,所 述步驟4)中計算新字符串Sl的步驟包括41)從左向右掃描SA數(shù)組中已排序的所有d-加權(quán)子串,依次比較相鄰的兩個d-加權(quán) 子串的大小,被比較的d-加權(quán)子串從0開始編號命名,如果兩個d-加權(quán)子串相等,則編號 一樣,否則后者編號等于前者的編號加1 ;42)把S中各個d-加權(quán)子串用其在步驟41)中獲取的編號來代替,所形成的新字符串 即為Si。
4.根據(jù)權(quán)利要求3所述的基于基數(shù)排序的字符串后綴數(shù)組構(gòu)造方法,其特征在于,所 述步驟6)中從SAl歸納計算SA的過程如下61)初始化SA的所有元素為-1,找出S中所有后綴在SA中所屬各桶的結(jié)束位置,從右 向左掃描SAl數(shù)組,對每個掃描到的元素SAl [i],如果suf(S,Pl [SAl [i]])是LMS后綴, 則把Pl [SAl [i]]放在后綴suf (S, Pl [SAl [i]])在SA中所屬桶的當(dāng)前結(jié)束位置,然后再把 該桶的結(jié)束位置向左移動一格;62)找出S中所有后綴在SA中所屬各桶的起始位置,從左向右掃描SA數(shù)組,對于掃描 到的每個不為-1的元素34[1],如果5[54[1]-1]是1^型,則把54[1]-1這個數(shù)值填入8吐(5, SA[i]-l)這個后綴在SA中所屬桶的當(dāng)前起始位置,然后再把該桶的起始位置向右移動一 格;63)找出S中所有后綴在SA中所屬各桶的結(jié)束位置,從右向左掃描SA數(shù)組,對于 掃描到的每個元素SA[i],如果S[SA[i]-l]是S型,則把SA[i]-l這個數(shù)值填入suf (S,SA[i]-l)這個后綴在SA中所屬桶的當(dāng)前結(jié)束位置,然后再把該桶的結(jié)束位置向左移動一 格,其中,把字符串S的所有后綴按其第一個字符在數(shù)組SA中進行排序,則所有第一個字 符相同的后綴都連續(xù)排列在SA中的某一段區(qū)域,這段區(qū)域我們稱之為對應(yīng)這些后綴的一 個桶。
全文摘要
本發(fā)明公開了一種基于基數(shù)排序的字符串后綴數(shù)組構(gòu)造方法,它包括1)從右向左掃描字符串S,比較當(dāng)前掃描的兩個相鄰字符S[i]和S[i+1],得出每個字符和后綴的類型,用數(shù)組t記錄;2)從左向右掃描數(shù)組t,找出所有d-字符出現(xiàn)的位置,獲取所有d-子串的首字母指針,用P1來記錄每個d-子串的指針;3)通過d-子串指針數(shù)組P1、數(shù)組B和SA來對S中所有的d-加權(quán)子串進行基數(shù)排序;4)根據(jù)3)排序的結(jié)果重新命名字符串S中的各個d-加權(quán)子串,形成縮短的新串S1;5)如果S1的每個字符都是唯一的,則直接排序S1的各后綴來計算S1的后綴數(shù)組SA1,否則以S1和SA1作為輸入?yún)?shù)遞歸調(diào)用SA-IS算法;6)根據(jù)5)中獲得的S1的后綴數(shù)組SA1歸納計算S的后綴數(shù)組SA;7)返回。
文檔編號G06F17/30GK102073740SQ20111002901
公開日2011年5月25日 申請日期2011年1月27日 優(yōu)先權(quán)日2011年1月27日
發(fā)明者農(nóng)革 申請人:農(nóng)革