【ゼットアルゴリズム】

Zアルゴリズム とは?

公開:
💡 途中からでも、先頭と何文字そろうかを数える

文字列の各位置から、文字列全体の先頭と何文字一致するかを線形時間で求めるアルゴリズム。パターンと本文をつなげると文字列検索にも使える。

📌 このページのポイント
aabcaab の各位置と先頭の一致長 位置 0 1 2 3 4 5 6 文字 a a b c a a b Z値 0 1 0 0 3 1 0 位置4:a a b → 先頭の a a b と一致
0始まり・Z[0]=0という流儀。位置4のaabは、先頭と3文字一致する。
ひよこ ひよこ
Z配列には何が入るの?
ペンギン先生 ペンギン先生
各位置からの文字列が、全体の先頭と何文字続けて一致するかだよ。aabcaabなら、0始まりの位置4からはaabで、先頭のaabと3文字一致する。だからZ[4]は3になるんだ。
ひよこ ひよこ
全部の位置で最初から比べるの?
ペンギン先生 ペンギン先生
それだと同じ比較を繰り返しやすいよね。Zアルゴリズムは、先頭と一致すると分かっている区間、Z-boxを利用するんだ。区間内の情報を再利用し、足りない部分だけ比較して右端を伸ばすので、長さnの文字列を全体でO(n)時間で扱えるよ。
ひよこ ひよこ
それがどう検索につながるの?
ペンギン先生 ペンギン先生
探す文字列P、どちらにも出ない区切り記号、本文TをつなげてZ配列を作るよ。本文に対応する位置でZ値がPの長さと一致すれば、そこからPが現れると分かる。Pがaba、Tがababaなら、本文の位置0と2が一致するんだ。
ひよこ ひよこ
Z[0]はどう数えるの?
ペンギン先生 ペンギン先生
先頭自身との一致なので、文字列長を入れる流儀も0を置く流儀もあるよ。このページと図では0とするね。位置を0から数えるか1から数えるかも資料で違うので、配列の定義と本文への位置の戻し方をそろえるのが大切なんだ。
もっと詳しく知りたい人へ

区切り記号や文字の単位には注意が必要ですか?

区切りにはパターンにも本文にも含まれない記号を使います。使える文字が制限されるなら、文字以外の番兵値を持つ配列にする方法もあります。バイト・コード単位・コードポイントなど、比較する単位と返す位置の単位も統一します。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「Zアルゴリズム」って出てきたら「各位置と先頭の一致長を、重複比較を減らして求める方法」と思えればだいたいOK!

参考資料

← 用語集にもどる