S について, 以下のように 辞書順 を定義する: (例)apple ≪ banana violet ≪ violin moral ≪ morale T ≪ S ⇔ 以下のいずれかが成り立つ: ある整数 i(0 ≤ i ≤ min(n, m))について, 0 ≤ j ≤ i − 1 である任意の整数 j に関して T j = S j ,かつ,t i < s i . 任意の整数 i(0 ≤ i ≤ min(n, m))について T j = S j ,かつ,n < m .
(1 ≤ i ≤ n−1) となる s[i]. S-type s[i] ≪ s[i+1] (1 ≤ i ≤ n−1) となる s[i] および s[n]. LMS-type s[i−1] が L-type かつ自身が S-type の s[i](2 ≤ i ≤ n) . position 1 2 3 4 5 6 7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • •
の suffix s[j] の 先頭1文字が等しいとき,s[i] ≪ s[j] が成り立つ. (証)s[i] = ax, s[j] = ay (a ∈ Σ, x, y ∈ Σ+) とする. x ≪ ax (= L-type) & ay (= S-type) ≪ y より, ① x[1] ≠ a & y[1] ≠ a ⇨ x[1] > a & y[1] < a より,x ≪ y . ② x[1] = a & y[1] ≠ a ⇨ y[1] < a より,x ≪ y . ③ x[1] ≠ a & y[1] = a ⇨ x[1] > a より,x ≪ y . ④ x[1] = y[1] = a ⇨ sx[2] と sy[2] について同様 .
① 先頭文字毎に配列にバケットを設定. ② S-type を各バケットの後方からソート順で格納. ③ 配列を前方から走査し, 見つけた s[i] に対して s[i−1] が L-type ⇨ バケットの空きの先頭に s[i−1] を追加. 逆も可能:L-type がソート済みなら,その順序を基にして S-type をソートできる. x ≪ y ⇨ ax ≪ ay 後方から走査・末尾に追加
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • 1. 先頭文字バケットを基に,LMS-type を配列に挿入 1. 配列に先頭文字ごとのバケットを設定 2. LMS-type を各バケットの末尾から挿入 SA bucket $ a b c d r
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • 1. 先頭文字バケットを基に,LMS-type を配列に挿入 1. 配列に先頭文字ごとのバケットを設定 2. LMS-type を各バケットの末尾から挿入 SA 12 8 4 6 bucket $ a b c d r
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除 SA 12 8 4 6 bucket $ a b c d r
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除 SA 12 8 4 6 bucket $ a b c d r
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 8 4 6 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 8 4 6 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 8 4 6 10 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 8 4 6 10 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 4 6 7 10 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 4 6 7 10 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 6 7 10 3 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 6 7 10 3 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 5 7 10 3 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 5 7 10 3 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 5 7 10 3 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 5 7 10 3 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 5 7 10 3 bucket $ a b c d r 2. LMS-type の順序を基に L-type を配列に挿入 1. 配列を前方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が L-type なら, s[i−1] を対応するバケットの空きの先頭に挿入 2. ss s[i] が LMS-type なら,配列から削除
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 9 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 9 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 6 9 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 6 9 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 4 6 9 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 4 6 9 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 1 4 6 9 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 1 4 6 9 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 8 1 4 6 9 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入
7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • SA 12 11 8 1 4 6 9 2 5 7 10 3 bucket $ a b c d r 3. L-type の順序を基に S-type を配列に挿入 1. 配列を後方から走査し,suffix を探索 1. 見つけた s[i] について,s[i−1] が S-type なら, s[i−1] を対応するバケットの空きの末尾に挿入 完
が間に LMS のない LMS-type のとき i 〜 j 番目,または,n 番目のみからなる部分文字列. position 1 2 3 4 5 6 7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • A = a c a B = a d a C = a b r a $ D = $
suffix の順序は LMS-substring の順序のみから求まる. position 1 2 3 4 5 6 7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • A = a c a B = a d a C = a b r a $ D = $ ABCD, BCD, CD, D の 順序は,A, B, C, D の 順序から求まる. a. LMS-sub 一意
suffix の順序は LMS-substring の順序のみから求まる. position 1 2 3 4 5 6 7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • A = a c a B = a d a C = a b r a $ D = $ ABCD, BCD, CD, D の 順序は,A, B, C, D の 順序から求まる. a. LMS-sub 一意 ⇨ LMS-type suffix をソートするには, LMS-substring をソートできればよい.
では,LMS-type の順序を 基準に L/S-type suffix をソートした. ⇨ より正確には,各 LMS-type を基準に, それより前の L/S-type suffix をソートした. position 1 2 3 4 5 6 7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • 毎回ひとつ前を 調べて挿入した ⇨ 共通する LMS-type を末尾にもつ suffix は, その末尾の順序を基準にソートできる.
を, その末尾文字の順序を最初の基準としてソートしている. ⇨ 各 LMS-substring の末尾文字をバケットに格納し induced sorting すれば LMS-substring をソートできる. position 1 2 3 4 5 6 7 8 9 10 11 12 T a b r a c a d a b r a $ L/S-type S S L S L S L S S L L S LMS-type • • • • 実際には,適当な順番で LMS-type をバケットに 突っ込み induced sorting するだけで SA が完成する.