ローリングハッシュ: 窓をずらしながら文字列を比べよう
ローリングハッシュは、文字列の区間ごとのハッシュ値を使って、部分文字列を高速に比べる方法です。
窓を1文字ずつずらしながら、区間の文字列を毎回作り直さずに数字として比べるイメージです。
使いどころ
- 同じ長さの部分文字列をたくさん比べる
- 文字列探索
- 重複する部分文字列を探す
手順
- 文字を数字に変える
- 最初の区間のハッシュ値を作る
- 窓を1つ右へずらす
- 古い文字を引き、新しい文字を足して更新する
図で見る
コピペ用コード
def rolling_hash(text, length):
base = 31
mod = 10**9 + 7
value = 0
power = pow(base, length - 1, mod)
result = []
for i, char in enumerate(text):
value = (value * base + ord(char)) % mod
if i >= length:
value = (value - ord(text[i - length]) * power) % mod
if i >= length - 1:
result.append(value)
return result
print(rolling_hash("abcde", 3))
コードの読み方
valueは、今見ている区間のハッシュ値です。baseは、文字の位置の重みを作るための数です。modは、値が大きくなりすぎないようにするための余りです。ord(char)で文字を数字に変えています。
注意点
ハッシュ値が同じでも、文字列が必ず同じとは限りません。必要なら最後に本当に一致しているか確認します。