Строки: база, полиномиальные хеши (9 октября 2017)
- Определения: подстрока, суффикс, префикс, период
- Поиск подстроки в строке
- C++ :
string.find(string)
, O(n2)
- Префикс функция
- Z-функция
- Алгоритм Боера-Мура'77 (и его модификация Чжу-Такаоки'87!)
- Полиномиальный хеш строки
- Цель: отобразить строки в целые числа, чтобы сравнивать их на равенство за O(1)
- Вычисление хеша:
h[i+1] = h[i]*P + s[i] ; substr(i, len) = h[i+len] - h[i]*deg[len]
. При P > |Σ| инъекция. А теперь вычисления делаем по модулю.
- Коллизии: Pr(s1,...,sn различны → h1,...hn различны) ≥ 1 - n(n-1)/(2M)
- Хеши, вероятности
- Lm: если (P,MOD) фиксировано, MOD простое, мы берём случайный многочлен, то вероятность, что P − корень, равна 1/MOD
- Lm: если многочлен и MOD фиксированы, MOD простое, мы берём случайное P, то вероятность, что P − корень, ≤ degree/MOD
- Lm: если MOD фиксирован, MOD простое, мы берём случайное P и случайный многочлен, то вероятность, что P − корень равна 1/MOD
- Анонс "строка Туэ-Морса", "тест против (P,MOD)-хеша".
- Что делать с коллизиями? Выбирать случайную точку P или случайный простой MOD! Лучше P.
− Перерыв −
- Хеши: теория
- В C++ есть встроенный
unordered_set<string>; hash<string>()
.
- Lm: сколько корней у случайного многочлена? Ответ: 1
- Всё-таки, нужна ли простота? По не простому модулю у многочлена может быть очень много корней. Пример: x32 ≡ 0(mod 232).
- Окончание доказательства:
- Случай не случайных строк (следствие из леммы 2) получаем "длина строки"/M
- Случай случайных строк (следствие из леммы 3) получаем 1/M
- Хеши: антихешовые тесты
- Строка Туэ-Морса (__builtin_popcount(i) mod 2, или рекурсивно: Sn = Sn-1 + not Sn-1). Оценка длины строки, чтобы была коллизия.
- [skipped] Тест против (P,MOD)-хеша. Алгоритм Капуна.
- Хеши: использование
- Алгоритм Рабина-Карпа
- Наибольшая общая подстрока двух строк за O(nlogn).