これが正しい答えかどうかはわかりませんが、とにかく:
ハッシュ値
を構築する際に、文字列ハッシュのセットで一致を確認できます。別名、現在のハッシュ値。ハッシュ関数/コードは通常、ループとして実装され、そのループ内にクイック ルックアップを挿入できます。
もちろん、m
文字列のセットから最大の文字列長を選択する必要があります。
更新:ウィキペディアから、
[...]
for i from 1 to n-m+1
if hs ∈ hsubs
if s[i..i+m-1] = a substring with hash hs
return i
hs := hash(s[i+1..i+m]) // <---- calculating current hash
[...]
現在のハッシュを段階的に計算しm
ます。各ステップには、ハッシュのセットで検索できる一時的なハッシュ値 (O(1) 複雑さ) があります。すべてのハッシュは同じサイズ、つまり 32 ビットになります。
更新 2:償却された (平均) O(n) 時間の複雑さ ?
上記でm
、最大文字列長が必要であると述べました。反対のことを利用できることがわかりました。部分文字列検索をシフトするためのハッシュと固定サイズ
により、O(n) の複雑さを実現できます。
可変長の文字列がある場合は、最小文字列長に設定できます。さらに、ハッシュのセットでは、ハッシュを文字列全体ではなく、文字列の最初の m 文字に関連付けます。
ここで、テキストを検索しながら、現在のハッシュがハッシュ セットに含まれているかどうかを確認し、関連する文字列が一致するかどうかを調べます。
この手法は誤報を増やしますが、平均して O(n) 時間の複雑さがあります。m
m