День 79
Nikita Nikler
8 января 2025, 18:22

Решал сейчас задачу вычисления полиномиального хеша для строки. В приложенной картинке приводится формула для расчета такого хеша. Где s - конкретный символ строки ,a - основание по которому считается хеш ,а m - модуль для вычисления хеша. И вроде все выглядит просто - вычислил числовой код символа через charCodeAt и поехал умножать и складывать по формуле в цикле ,а в конце берем по модулю.

Но вот проблема. При больших строках и основании {a} получаются числа ,выходящие за диапазон точных целых чисел 2^53 - 1. А результате чего получается ситуация ,что берем число Infinity по модулю {m} ,что даст NaN.

Оказалось есть другая формула ,которая помогает избежать переполнения путем вычисления модуля на каждой итерации:

hash = (hash * a + s) % m.

И это работает! Числа не переполняются ,тк вычисление по модулю происходит на каждой итерации и значение не превосходит m. Может быть в теории где-то была эта формула ,и я про нее забыл. Но без подсказки решить не смог бы.. Вот не знаю даже ,что делать с этими формулами ,стоит ли их запоминать или нет.. Надеюсь ,на собесе не будут попадаться подобные задачи.

Была еще мысль использовать BigInt ,но это бы сильно замедлило алгоритм. Причем я помню ,была какая-то задача тоже с переполнением ,где я переписал Number на BigInt и алгоритм проваливал тест по TimeLimit.

Нравится? Расскажите друзьям!
Комментировать
Перейти к записи в ленте
Цель

Вы тоже можете
опубликовать свою
цель здесь

Мы поможем вам ее достичь!

310 000

единомышленников

инструменты

для увлекательного достижения

Присоединиться
Регистрация

Регистрация

Уже зарегистрированы?
Быстрая регистрация через соцсети
Вход на сайт

Входите.
Открыто.

Еще не зарегистрированы?
 
Войти через соцсети
Забыли пароль?