
- •Граф. Ориентированный граф. Представления графа. Обход графа в глубину и в ширину.
- •Топологическая сортировка. Подсчет числа путей в орграфе.
- •Сильно связные компоненты.
- •Поиск кратчайших путей в графе. Алгоритм Флойда. Алгоритм Дейкстры. Алгоритм Форда-Беллмана.
- •Алгоритм a*. Эвристики.
- •Минимальное остовное дерево. Алгоритм Прима. Биномиальная куча.
- •Амортизационная стоимость. Фибоначчиева куча. Амортизационная стоимость (анализ)
- •Метод потенциалов
- •Фибоначчиева Куча
- •Структура
- •Время работы
- •Система непересекающихся множеств. Алгоритм Крускала.
- •Наивная реализация
- •Эвристика сжатия пути
- •Эвристика объединения по рангу
- •Потоки, Форда-Фалкерсона.
- •Декартово дерево
- •Дерево Фенвика. Дерево отрезков и динамическое программирование для rmq.
- •Сведение rmq к lca и наоборот.
- •Препроцессинг
- •Ответы на запросы
- •Алгоритм
- •Доказательство
- •Сложность
- •Алгоритм
- •Минимум внутри блока
- •Результат
- •Поиск нескольких минимумов на отрезке. Задача поиска подстрок. Алгоритм Рабина-Карпа. Конечный автомат. Алгоритм Бойера-Мура.
- •Метод хеширования
- •Алгоритм
- •Время работы
- •Алгоритм Бойера-Мура
- •Поиск со звездочками. Алгоритм Кнута-Морриса-Пратта.
- •Время работы
- •Алгоритм Ахо-Корасика.
- •Дерево ключевых слов (бор)
- •Пример дерева ключевых слов (бора)
- •Построение бора
- •Поиск строки в бору
- •Автомат Ахо-Корасик
- •Суффиксное дерево, Алгоритм Укконена.
- •2. Квадратичный алгоритм
- •3. Линейный алгоритм
- •Суффиксный массив.
- •Наивный алгоритм поиска
- •Алгоритм, использующий префиксы циклических сдвигов
- •Исключения
- •Шаблоны
- •Stl: итераторы
- •Сортировка и поиск в stl. Алгоритмы stl
- •Куча в stl. Алгоритмы stl.
- •Ассоциативный массив. Интерфейс, варианты реализации.
Результат
Итого,
на предподсчёт требуется
времени
и памяти, а ответ на запрос вычисляется
за
.
Поиск нескольких минимумов на отрезке. Задача поиска подстрок. Алгоритм Рабина-Карпа. Конечный автомат. Алгоритм Бойера-Мура.
Поиск нескольких минимумов на отрезке.
Если требуется получать сразу несколько минимумов по отрезку (всегда n минимумов на отрезке) – делаем дерево отрезков с функцией нахождения этих нескольких минимумов (но придется делать k сравнений в k раз усложняет время)
Альтернатива
Надо найти k минимумов. Находим по RMQ – индекс первого. Потом запускаем RMQ на подмассивах, на которые делится наш массив найденным индексом. Так найдем уже 3 минимума. И т.д. (на 4 подмассивах и т.д.)
Поиск подстроки в строке.
Имеются
строки
и
такие,
что
и
элементы этих строк
символы
из конечного алфавита
.
Говорят, что строка
встречается
в строке
со
сдвигом
,
если
и
=
.
Если строка
встречается
в строке
,
то
является
подстрокой
.
Требуется проверить, является ли
строка
подстрокой
.
В задачах поиска традиционно принято обозначать шаблон поиска как needle а строку, в которой ведётся поиск — как haystack . Также обозначим через Σ алфавит, на котором проводится поиск.
Если считать, что строки нумеруются с 1, простейший алгоритм (англ. brute force algorithm, naïve algorigthm) выглядит так.
for i=0...|haystack|-|needle|
for j=1...|needle|
if haystack[i+j]<>needle[j]
then goto 1
output("Найдено: ", i+1)
1:
Простейший алгоритм поиска даже в лучшем случае проводит |haystack|−|needle|+1 сравнение; если же есть много частичных совпадений, скорость снижается до O(|haystack|·|needle|).
Показано, что примитивный алгоритм отрабатывает в среднем 2h сравнений
Метод хеширования
Для
решения задачи удобно использовать
полиномиальный хеш, так его легко
пересчитывать:
,
где
—
это некоторое простое число, а
—
некоторое большое число, для уменьшения
числа коллизий (обычно берётся
или
,
чтобы модуль брался автоматически при
переполнении типов). Стоит обратить
внимание, что если 2 строчки имеют
одинаковый хэш, то они в большинстве
таких случаев равны.
При удалении первого символа строки и добавлении символа в конец считать хеш новой строки при помощи хеша изначальной строки возможно за :
.
.
Получается :
.
Следует учесть, что при получении отрицательного значения необходимо прибавить .
Алгоритм
Алгоритм
начинается с подсчета
и
.
Для
вычисляется
и
сравнивается с
.
Если они оказались равны, то
образец
содержится
содержится в строке
,
начиная с позиции
,
но в этом случае возможны ложные
срабатывания алгоритма. Если требуется
свести такие срабатывания к минимуму
или исключить вообще, то применяют
сравнение некоторых символов из этих
строк, которые выбраны случайным образом,
или применяют явное сравнение строк,
как в наивном
алгоритме поиска подстроки в строке.
В первом случае проверка произойдет
быстрее, но вероятность ложного
срабатывания останется хоть и небольшая,
во втором случае проверка займет время
равное длине образца, но исключит
возможность ложного срабатывания.
Для
ускорения работы алгоритма оптимально
предпосчитать
.
Если шаблон большой, нет большого увеличения по времени. Каждый шаг цикла не зависит от остальных (распараллеливание)