День 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

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

инструменты

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

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

Можливості
безмежні.
Настав час
відкрити свої.

Уже зарегистрированы?
Вхід на сайт

Заходьте.
Відкрито.

Ще не зареєстровані?
 
Підключіться до будь-якого з ваших акаунтів, ваші дані будуть взяті з акаунту.
Забули пароль?