SlideShare a Scribd company logo
1 of 91
Download to read offline
文字列アルゴリズム
北海道大学 理学部 化学科 B3 TAB
参考資料
• snuke さんのブログ

文字列の頭いい感じの線型アルゴリズムたち

(MP, KMP, Manacher, Z-algorithm)
• Competitive Programmer s Handbook

海外版の蟻本的なもの (Z-algorithm)
• Codeforces の記事 (Z-algorithm)
• @kyuridenamida さんのスライド (KMP, BM, など)
• potatosensei さんのブログ (KMP)
今回の発表内容
• Manacher s algorithm
• Z-algorithm
• MP 法
• KMP 法
今回使う記号
• ¦S¦ : 文字列 S の長さ
• S[i] : 文字列 S の i 文字目(0-indexed とする)
• S[i, j] : 文字列 S の i 文字目から j 文字目までを取り出し
た文字列
Manacher s algorithm
文字列 S に対して, S[i] を中心とした回文(奇数長)の半径
の最大値を各 i に対して求めるアルゴリズム。

全体で O(¦S¦)



回文の半径:(回文の長さ + 1) / 2

例えば, TABAT の半径は 3
S a b a a a b a b a
R 1 2 1 4 1 2 3 2 1
ベースとなるアイデア
S
赤、グレーを中心とした回文の半径はすでにわかっている


黒を中心とした回文の半径が知りたい
→グレーを中心とした時の値を見れば良い
 黒を中心とした時と、グレーを中心とした時は同じ値
ベースとなるアイデア
S
赤、グレーを中心とした回文の半径はすでにわかっている


黒を中心とした回文の半径が知りたい
→グレーを中心とした時の値を見れば良い
 黒を中心とした時と、グレーを中心とした時は同じ値
ベースとなるアイデア
S
回文が中心をまたいでいても同じことが言える。
ベースとなるアイデア
S
緑の回文が黄色の回文の外に出ている場合
黒を中心とした回文の半径の最大値と、緑の回文の半径が同じとは限らない



→今わかっている範囲で伸ばせるところまでは伸ばして、残りは愚直に求める
ベースとなるアイデア
S
緑の回文が黄色の回文の外に出ている場合
黒を中心とした回文の半径の最大値と、緑の回文の半径が同じとは限らない



→今わかっている範囲で伸ばせるところまでは伸ばして、残りは愚直に求める
ベースとなるアイデア
S
緑の回文が黄色の回文の外に出ている場合
黒を中心とした回文の半径の最大値と、緑の回文の半径が同じとは限らない



→今わかっている範囲で伸ばせるところまでは伸ばして、残りは愚直に求める
ベースとなるアイデア
左側から順番に半径の最大値を求めていくことを考える。
赤を中心とした回文は何なのか?

→すでに見つけた回文の中で、右側が最も右にあるものを

 覚えておけば良い。
上のようになったら黒を中心とした回文をベースとする。
ソースコード
計算量の解析
while 文中の ++j が何回実行されるかを考える

j =R[c] + c - i より

i + j = R[c] + c

while 文を抜けた後, 

R[i] = j, c = i としているので, i + j = R[c] + c が成り立つ

i + j < ¦S¦ なので, ++j された回数は全体で O(¦S¦) である

従って for 文と合わせて全体でも O(¦S¦) である
Manacher s algorithm
偶数長の回文は検出できないの?

Manacher s algorithm
偶数長の回文は検出できないの?

→できます!
Manacher s algorithm
偶数長の回文は検出できないの?

→できます!
S = aabbaa の時、 S = $a$a$b$b$a$a$ として

S に対して Manacher s algorithm を適用すればよい
Z-algorithm
文字列 S が与えられた時、各 i に対して、S と S[i,¦S¦-1]
の最長共通接頭辞の長さを O(¦S¦) で求めるアルゴリズム
S = aabaabaaa と S[3,8] = aabaaa の最長共通接頭辞
は aabaa 

従って A[3] = ¦ aabaa ¦ = 5
0 1 2 3 4 5 6 7 8
S a a b a a b a a a
A 9 1 0 5 1 0 2 2 1
ベースとなるアイデア
S
黄色同士が同じ文字列の時、黒と緑は同じ文字列
ベースとなるアイデア
S
緑の文字列が黄色の文字列から飛び出している場合、緑と黒が同じとは言えない。
→黄色の文字列に収まっている部分については同じであると言える。

 飛び出している部分は愚直に比較する。
ベースとなるアイデア
S
緑の文字列が黄色の文字列から飛び出している場合、緑と黒が同じとは言えない。
→黄色の文字列に収まっている部分については同じであると言える。

 飛び出している部分は愚直に比較する。
ソースコード
Z-algorithm 使用例
求めた配列は結局何に使えるの?

Z-algorithm 使用例
求めた配列は結局何に使えるの?

→例えば文字列検索に使えます
Z-algorithm 使用例
求めた配列は結局何に使えるの?

→例えば文字列検索に使えます
文字列検索:テキスト文字列から、パターン文字列を探すこと
Z-algorithm 使用例
求めた配列は結局何に使えるの?

→例えば文字列検索に使えます
文字列検索:テキスト文字列から、パターン文字列を探すこと
どうやるの?
Z-algorithm 使用例
求めた配列は結局何に使えるの?

→例えば文字列検索に使えます
文字列検索:テキスト文字列から、パターン文字列を探すこと
どうやるの?
テキスト文字列を S パターン文字列を T とすると、

T + # + S に対して Z-algorithm で配列を求めればよい。 

A[i] = ¦T¦ となっている i を見つければ良い。
MP 法
A[i] := S[0,i-1] の接頭辞と接尾辞が最大何文字一致しているか
(ただし、¦S[0,i-1]¦ 未満のもののみを考える)

(この配列 A は最長ボーダーというらしい)
最長ボーダー A を O(¦S¦) で求めるアルゴリズム。




S[0, 5] = aabaab

S[0,2] = aab = S[3,5]

従って、 A[6] = 3
S a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
ベースとなるアイデア
S
赤と緑が一致している場合
→A[i+1] = A[i] + 1 とすれば良い
S[i]
A[i]
S[A[i]]
ベースとなるアイデア
S
赤と緑が違う場合

S[i]
S[A[i]]
S[A[A[i]]]
ベースとなるアイデア
S
赤と緑が違う場合

S[i]
S[A[i]]
S[A[A[i]]]
ベースとなるアイデア
S
赤と緑が違う場合

→赤と水色を比較する
S[i]
S[A[i]]
S[A[A[i]]]
ソースコード
計算量の解析
while 文が何回実行されるかを考える



while 文が実行されると, j の値は減る

(-1 よりは小さくならない)



従って j の増加量  j の減少量 while 文の実行回数



j が増えるのは ++j しかないので, j の増加量 = ¦S¦

従って while 文が ¦S¦ より多く実行されることはない

従って全体で O(¦S¦) である
≥ ≥
MP 法
最長ボーダーって結局何に使えるの?

→最長ボーダーを使うことで解ける競プロの問題が色々ある
一般的に有名なのは文字列検索
文字列の周期性の判定も行える

(http://snuke.hatenablog.com/entry/
2015/04/05/184819)
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
不一致
2 - A[2] = 1 文字ずらす
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
不一致
8 - A[8] = 3 文字ずらす
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
一致
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
a a b a a b a a a
MP 法による文字列検索
パターン文字列 T の i 文字目で不一致

→ i - A[i] 文字, パターン文字列をずらす

S = aaabaabaabaaa , T = aabaabaaa 



a a a b a a b a a b a a a
0 1 2 3 4 5 6 7 8 9
T a a b a a b a a a
A -1 0 1 0 1 2 3 4 5 2
MP 法による文字列検索
テキスト文字列中の見ている場所が後ろに下がることがない

→全体で O(¦S¦ + ¦T¦)



KMP 法
Knuth + MP で KMP

MP を高速化したもの。

パターン文字列をずらす時に賢くずらす。

最悪時のオーダーは MP と変わらず O(¦S¦ + ¦T¦)
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
不一致
b
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
不一致
b
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
不一致
b
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
不一致
b
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
不一致
b
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
不一致
b
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
不一致
b
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
一致
b
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
MP との違い
S b a a a a a a a
A -1 0 1 2 3 4 5 6
a ではないことがわかっているのに、a と比較するのは無駄

a 以外の文字が出てくるところまで、飛ばしてしまって良い

7 文字目で不一致になったら次は 0 文字目を見るようにする
MP を用いた文字列検索で、i 文字目で不一致になった時、

次に比較する場所に黒い線が伸びています
ソースコード
練習問題
• http://codeforces.com/contest/914/problem/F
• http://codeforces.com/contest/808/problem/G
• https://beta.atcoder.jp/contests/jag2018summer-day2/
tasks/jag2018summer_day2_h
• https://beta.atcoder.jp/contests/ukuku09/tasks/
ukuku09_d
• https://beta.atcoder.jp/contests/arc058/tasks/arc058_d

More Related Content

What's hot

Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話Nagisa Eto
 
色々なダイクストラ高速化
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化yosupo
 
ユークリッド最小全域木
ユークリッド最小全域木ユークリッド最小全域木
ユークリッド最小全域木理玖 川崎
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門Yoichi Iwata
 
LCA and RMQ ~簡潔もあるよ!~
LCA and RMQ ~簡潔もあるよ!~LCA and RMQ ~簡潔もあるよ!~
LCA and RMQ ~簡潔もあるよ!~Yuma Inoue
 
プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造Takuya Akiba
 
CODE FESTIVAL 予選B 解説
CODE FESTIVAL 予選B 解説CODE FESTIVAL 予選B 解説
CODE FESTIVAL 予選B 解説AtCoder Inc.
 
AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説AtCoder Inc.
 
充足可能性問題のいろいろ
充足可能性問題のいろいろ充足可能性問題のいろいろ
充足可能性問題のいろいろHiroshi Yamashita
 
2SAT(充足可能性問題)の解き方
2SAT(充足可能性問題)の解き方2SAT(充足可能性問題)の解き方
2SAT(充足可能性問題)の解き方Tsuneo Yoshioka
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界Preferred Networks
 
AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Inc.
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドMasaki Hara
 
プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法Takuya Akiba
 

What's hot (20)

Rolling Hashを殺す話
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話
 
arc047
arc047arc047
arc047
 
色々なダイクストラ高速化
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化
 
双対性
双対性双対性
双対性
 
ユークリッド最小全域木
ユークリッド最小全域木ユークリッド最小全域木
ユークリッド最小全域木
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門
 
LCA and RMQ ~簡潔もあるよ!~
LCA and RMQ ~簡潔もあるよ!~LCA and RMQ ~簡潔もあるよ!~
LCA and RMQ ~簡潔もあるよ!~
 
プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造
 
CODE FESTIVAL 予選B 解説
CODE FESTIVAL 予選B 解説CODE FESTIVAL 予選B 解説
CODE FESTIVAL 予選B 解説
 
AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説AtCoder Regular Contest 044 解説
AtCoder Regular Contest 044 解説
 
全域木いろいろ
全域木いろいろ全域木いろいろ
全域木いろいろ
 
Convex Hull Trick
Convex Hull TrickConvex Hull Trick
Convex Hull Trick
 
グラフネットワーク〜フロー&カット〜
グラフネットワーク〜フロー&カット〜グラフネットワーク〜フロー&カット〜
グラフネットワーク〜フロー&カット〜
 
充足可能性問題のいろいろ
充足可能性問題のいろいろ充足可能性問題のいろいろ
充足可能性問題のいろいろ
 
2SAT(充足可能性問題)の解き方
2SAT(充足可能性問題)の解き方2SAT(充足可能性問題)の解き方
2SAT(充足可能性問題)の解き方
 
ACPC 2018 Day3 G: 回文部分列 (Palindromic Subsequences)
ACPC 2018 Day3 G: 回文部分列 (Palindromic Subsequences)ACPC 2018 Day3 G: 回文部分列 (Palindromic Subsequences)
ACPC 2018 Day3 G: 回文部分列 (Palindromic Subsequences)
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
 
AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
 
プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法
 

More from HCPC: 北海道大学競技プログラミングサークル

More from HCPC: 北海道大学競技プログラミングサークル (20)

写像 12 相
写像 12 相写像 12 相
写像 12 相
 
ACPC 2017 Day3 F: 掛け算は楽しい
ACPC 2017 Day3 F: 掛け算は楽しいACPC 2017 Day3 F: 掛け算は楽しい
ACPC 2017 Day3 F: 掛け算は楽しい
 
ACPC 2017 Day3 D: 優柔不断
ACPC 2017 Day3 D: 優柔不断ACPC 2017 Day3 D: 優柔不断
ACPC 2017 Day3 D: 優柔不断
 
ACPC 2019 Day3 G: Restricted DFS
ACPC 2019 Day3 G: Restricted DFSACPC 2019 Day3 G: Restricted DFS
ACPC 2019 Day3 G: Restricted DFS
 
ACPC 2019 Day3 F: 部分文字列分解
ACPC 2019 Day3 F: 部分文字列分解ACPC 2019 Day3 F: 部分文字列分解
ACPC 2019 Day3 F: 部分文字列分解
 
ACPC 2019 Day3 E: 総和の切り取り
ACPC 2019 Day3 E: 総和の切り取りACPC 2019 Day3 E: 総和の切り取り
ACPC 2019 Day3 E: 総和の切り取り
 
ACPC 2019 Day3 B: パフェ
ACPC 2019 Day3 B: パフェACPC 2019 Day3 B: パフェ
ACPC 2019 Day3 B: パフェ
 
ACPC 2019 Day3 A: 間違い探し
ACPC 2019 Day3 A: 間違い探しACPC 2019 Day3 A: 間違い探し
ACPC 2019 Day3 A: 間違い探し
 
HUPC 2019 Day2 G: 木
HUPC 2019 Day2 G: 木HUPC 2019 Day2 G: 木
HUPC 2019 Day2 G: 木
 
HUPC 2019 Day2 E: ジャム
HUPC 2019 Day2 E: ジャムHUPC 2019 Day2 E: ジャム
HUPC 2019 Day2 E: ジャム
 
HUPC 2019 Day2 H: Revenge of UMG
HUPC 2019 Day2 H: Revenge of UMGHUPC 2019 Day2 H: Revenge of UMG
HUPC 2019 Day2 H: Revenge of UMG
 
HUPC 2019 Day2 F: MOD Rush
HUPC 2019 Day2 F: MOD RushHUPC 2019 Day2 F: MOD Rush
HUPC 2019 Day2 F: MOD Rush
 
HUPC 2019 Day2 C: 串刺し
HUPC 2019 Day2 C: 串刺しHUPC 2019 Day2 C: 串刺し
HUPC 2019 Day2 C: 串刺し
 
HUPC 2019 Day1 F: グリッドの番号
HUPC 2019 Day1 F: グリッドの番号HUPC 2019 Day1 F: グリッドの番号
HUPC 2019 Day1 F: グリッドの番号
 
HUPC 2019 Day1 E: 最短経路の復元
HUPC 2019 Day1 E: 最短経路の復元HUPC 2019 Day1 E: 最短経路の復元
HUPC 2019 Day1 E: 最短経路の復元
 
HUPC 2019 Day1 D: 貪欲が最適?
HUPC 2019 Day1 D: 貪欲が最適?HUPC 2019 Day1 D: 貪欲が最適?
HUPC 2019 Day1 D: 貪欲が最適?
 
HUPC 2019 Day1 C: 短絡評価
HUPC 2019 Day1 C: 短絡評価HUPC 2019 Day1 C: 短絡評価
HUPC 2019 Day1 C: 短絡評価
 
HUPC 2019 Day1 B: 自身の 2 倍
HUPC 2019 Day1 B: 自身の 2 倍HUPC 2019 Day1 B: 自身の 2 倍
HUPC 2019 Day1 B: 自身の 2 倍
 
HUPC 2019 Day1 A: four tea
HUPC 2019 Day1 A: four teaHUPC 2019 Day1 A: four tea
HUPC 2019 Day1 A: four tea
 
プログラミングコンテスト基礎テクニック
プログラミングコンテスト基礎テクニックプログラミングコンテスト基礎テクニック
プログラミングコンテスト基礎テクニック
 

Recently uploaded

新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールsugiuralab
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価sugiuralab
 

Recently uploaded (7)

新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツール
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価
 

文字列アルゴリズム