リリース・改善中
Algorithm
文字列アルゴリズムはテキスト中のパターン検索や接頭辞による単語検索を扱う手法で、KMP、Rabin-Karp、トライ、Z アルゴリズムが代表的です。
文字列アルゴリズムは、文字の並びを速く正確に比較・検索するための手法です。中心となる問題はパターン照合で、長いテキストの中に短いパターンが現れる位置をすべて見つけます。辞書から特定の接頭辞で始まる単語を探す問題や、多数のパターンを一度に探す問題もこの分野に含まれます。すべての位置で一文字ずつ比べる素朴な方法は、最悪の場合テキスト長とパターン長の積に比例する時間がかかります。
エディタの検索、ログ検索、検索窓の入力補完、侵入検知、ファイル同期、ゲノム解析は、いずれも文字列アルゴリズムの上に成り立っています。KMP は失敗表によってすでに行った比較を再利用し線形時間を保証し、Rabin-Karp はローリングハッシュでウィンドウを一つずつずらして比較を減らし、トライは共通の接頭辞を共有して単語の長さだけに比例する時間で接頭辞検索を行います。コーディング面接でもよく出題されるテーマです。
まず接頭辞、接尾辞、境界(border)といった用語を覚え、素朴な照合がなぜ遅いのかを手で確かめるとよいでしょう。次に小さなパターンで接頭辞関数の表を自分で計算し、KMP 検索とトライを実装して標準ライブラリの結果と比べて検証します。最後に、ハッシュの衝突や Unicode 正規化など、実務で結果を誤らせる落とし穴を確認します。
パターンの各接頭辞について最長の境界の長さを前計算し、不一致のときはテキストを戻さずに短い境界へ移ることで O(n + m) で検索します。
Rabin-Karp は長さ m のウィンドウのハッシュを O(1) で更新してパターンのハッシュと比べ、一致したときだけ実際の文字を比較して確かめます。
文字をたどって下っていく木で、共通の接頭辞を一つの経路で共有するため、接頭辞検索や入力補完を単語の長さに比例する時間で処理できます。
Z 配列は各位置から始まる接尾辞と文字列全体の最長共通接頭辞の長さを線形時間で求めます。実際のテキストでは正規化とインデックスの単位にも注意が必要です。
prefix_function はパターンの各接頭辞の最長の境界の長さを計算し、kmp_search はその表を使ってテキストを左から右へ一度だけ読み、パターンが始まる位置をすべて集めます。一致のあと k を pi[k - 1] に戻すため、位置 0 と 2 のように重なる出現も見つかります。python string_search.py で実行すると二つの結果が表示されます。
string_search.py
def prefix_function(p: str) -> list[int]:
"""pi[i] = length of the longest proper border of p[:i + 1]."""
pi = [0] * len(p)
k = 0
for i in range(1, len(p)):
while k > 0 and p[i] != p[k]:
k = pi[k - 1]
if p[i] == p[k]:
k += 1
pi[i] = k
return pi
def kmp_search(text: str, pattern: str) -> list[int]:
"""Start positions of every (possibly overlapping) occurrence."""
if not pattern:
return list(range(len(text) + 1))
pi = prefix_function(pattern)
hits, k = [], 0
for i, ch in enumerate(text):
while k > 0 and ch != pattern[k]:
k = pi[k - 1]
if ch == pattern[k]:
k += 1
if k == len(pattern):
hits.append(i - k + 1)
k = pi[k - 1]
return hits
if __name__ == "__main__":
print(prefix_function("ababaca")) # [0, 0, 1, 2, 3, 0, 1]
print(kmp_search("abababcabab", "abab")) # [0, 2, 7]
python string_search.pyインストールから 文字列アルゴリズム の中心となる考え方まで、6 章で順を追って学びます。
文字列アルゴリズム について質問し、経験を共有し、意見を交わす場所です。
まだディスカッションはありません。最初の話題を始めましょう。
コメント 0件
ログイン · ログインするとコメントできます。
最初のコメントを書いてみましょう。