Ответ 1
Я не уверен, что это правильный ответ, но в любом случае:
При построении хеш-значения мы можем проверить соответствие в наборе хешей строк. Aka, текущее значение хэш-функции. Хеш-функция/код обычно реализуется как цикл, и внутри этого цикла мы можем вставить наш быстрый поиск.
Конечно, мы должны выбрать 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
должен иметь максимальную длину строки. Оказывается, мы можем использовать противоположное.
С хеширование для переключения поиска подстроки и фиксированный размер m
мы можем достичь сложности O (n).
Если у нас есть строки с переменной длиной, мы можем установить m
на минимальную длину строки. Кроме того, в наборе хэшей мы не связываем хэш со всей строкой, а с первыми m-символами.
Теперь, просматривая текст, мы проверяем, находится ли текущий хэш в хэш-наборе, и мы проверяем связанные строки для соответствия.
Этот метод будет увеличивать ложные тревоги, но в среднем он имеет сложность времени O (n).