Хеширование строк: различия между версиями
Перейти к навигации
Перейти к поиску
Ctrlalt (обсуждение | вклад) Нет описания правки |
Ctrlalt (обсуждение | вклад) (→Ссылки) |
||
Строка 101: | Строка 101: | ||
* [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8_%D0%B2_%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B5_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%85%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F._%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A0%D0%B0%D0%B1%D0%B8%D0%BD%D0%B0-%D0%9A%D0%B0%D1%80%D0%BF%D0%B0 neerc.ifmo.ru — Поиск подстроки в строке с использованием хеширования. Алгоритм Рабина-Карпа] | * [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8_%D0%B2_%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B5_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%85%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F._%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A0%D0%B0%D0%B1%D0%B8%D0%BD%D0%B0-%D0%9A%D0%B0%D1%80%D0%BF%D0%B0 neerc.ifmo.ru — Поиск подстроки в строке с использованием хеширования. Алгоритм Рабина-Карпа] | ||
* [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8_%D0%B4%D0%B2%D1%83%D1%85_%D1%81%D1%82%D1%80%D0%BE%D0%BA_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%85%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F neerc.ifmo.ru — Поиск наибольшей общей подстроки двух строк с использованием хеширования] | * [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BD%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%D0%B9_%D0%BE%D0%B1%D1%89%D0%B5%D0%B9_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8_%D0%B4%D0%B2%D1%83%D1%85_%D1%81%D1%82%D1%80%D0%BE%D0%BA_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%85%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F neerc.ifmo.ru — Поиск наибольшей общей подстроки двух строк с использованием хеширования] | ||
* [https://ru.algorithmica.org/cs/hashing/polynomial/ ru.algorithmica.org — Полиномиальное хеширование] | |||
* [http://habrahabr.ru/post/142589/ habrahabr.ru — Полиномиальные хеши и их применение] | * [http://habrahabr.ru/post/142589/ habrahabr.ru — Полиномиальные хеши и их применение] | ||
* [http://codeforces.com/blog/entry/4898 codeforces.com — Anti-hash test] | * [http://codeforces.com/blog/entry/4898 codeforces.com — Anti-hash test] | ||
* [http://codeforces.com/blog/entry/60445 codeforces.com — Полиномиальное хеширование + разбор интересных задач] | * [http://codeforces.com/blog/entry/60445 codeforces.com — Полиномиальное хеширование + разбор интересных задач] | ||
* [https://blog.algoprog.ru/hash-no-multiply/ Калинин П. — Про хеширование без домножения] | * [https://blog.algoprog.ru/hash-no-multiply/ Калинин П. — Про хеширование без домножения] | ||
* [https://usaco.guide/gold/string-hashing?lang=cpp usaco.guide — String Hashing] | |||
Код: | Код: | ||
* [https://github.com/indy256/codelibrary/blob/master/cpp/strings/hashing.cpp codelibrary/cpp/strings/hashing.cpp] | * [https://github.com/indy256/codelibrary/blob/master/cpp/strings/hashing.cpp codelibrary/cpp/strings/hashing.cpp] |
Версия от 09:52, 7 декабря 2021
hi = s0xn - 1 + s1xn - 2 + ... + sn - 2x + sn - 1.
struct Hasher { long long x = 31, mod = 1e9 + 7; vector<long long> p, h; Hasher(const string &s) { p.resize(s.size()); h.resize(s.size()); p[0] = 1; h[0] = s[0] - 'a' + 1; for (int i = 1; i < s.size(); i++) { p[i] = p[i - 1] * x % mod; h[i] = (h[i - 1] * x % mod + s[i] - 'a' + 1) % mod; } } long long getHash(int l, int r) { long long res = h[r]; if (l) res = (res - p[r - l + 1] * h[l - 1] % mod + mod) % mod; return res; } };
hi = s0 + s1x + s2x2 + ... + sn - 1xn - 1. Для выравнивания хеши различных подстрок домножаются на xn - 1 - L. struct Hasher { long long x = 31, mod = 1e9 + 7; vector<long long> p, h; Hasher(const string &s) { p.resize(s.size()); h.resize(s.size()); p[0] = 1; h[0] = s[0] - 'a' + 1; for (int i = 1; i < s.size(); i++) { p[i] = p[i - 1] * x % mod; h[i] = (h[i - 1] + p[i] * (s[i] - 'a' + 1) % mod) % mod; } } long long getHash(int l, int r) { long long res = h[r]; if (l) res = (res - h[l - 1] + mod) % mod; res = res * p[p.size() - 1 - l] % mod; return res; } }; Этот способ непригоден для сравнения участков двух строк разной длины. В данном случае хеш более левого участка следует домножать на x|L1 - L2|. |
hi = s0 + s1x + s2x2 + ... + sn - 1xn - 1. Для выравнивания хеши различных подстрок домножаются на (x-1)L. struct Hasher { long long x = 31, xi = 129032259, mod = 1e9 + 7; vector<long long> p, pi, h; Hasher(const string &s) { p.resize(s.size()); pi.resize(s.size()); h.resize(s.size()); p[0] = pi[0] = 1; h[0] = s[0] - 'a' + 1; for (int i = 1; i < s.size(); i++) { p[i] = p[i - 1] * x % mod; pi[i] = pi[i - 1] * xi % mod; h[i] = (h[i - 1] + p[i] * (s[i] - 'a' + 1) % mod) % mod; } } long long getHash(int l, int r) { long long res = h[r]; if (l) { res = (res - h[l - 1] + mod) % mod; res = (res * pi[l]) % mod; } return res; } }; |
Ссылки
Теория:
- e-maxx.ru — Алгоритмы хэширования в задачах на строки
- neerc.ifmo.ru — Поиск подстроки в строке с использованием хеширования. Алгоритм Рабина-Карпа
- neerc.ifmo.ru — Поиск наибольшей общей подстроки двух строк с использованием хеширования
- ru.algorithmica.org — Полиномиальное хеширование
- habrahabr.ru — Полиномиальные хеши и их применение
- codeforces.com — Anti-hash test
- codeforces.com — Полиномиальное хеширование + разбор интересных задач
- Калинин П. — Про хеширование без домножения
- usaco.guide — String Hashing
Код:
Задачи: