- •Содержание
- •Введение.
- •1. Основы анализа алгоритмов
- •1.1. Сравнительные оценки алгоритмов
- •1.2. Элементарные операции в формальной системе
- •1.3. Классы входных данных
- •1.4. Классификация алгоритмов по виду функции трудоемкости
- •1.5. Классификация скоростей роста. Асимптотический анализ функций
- •1. Оценка (тета)
- •2. Оценка о (о большое)
- •3. Оценка (Омега)
- •1.6. Эффективность рекурсивных алгоритмов
- •1.7. Анализ программ
- •1.8. Вопросы для самоконтроля
- •Классификация алгоритмов по виду функции трудоемкости.
- •2. Алгоритмы поиска и выборки
- •2.1. Последовательный поиск
- •2.2. Двоичный поиск
- •2.3. Задача выборки
- •2.4. Вопросы для самоконтроля
- •3.Алгоритмы сортировки
- •3.1. Сортировка трех чисел по месту
- •3.2. Сортировка вставками
- •3.3. Пузырьковая сортировка
- •3.4. Сортировка Шелла.
- •3.5. Корневая сортировка
- •3.6. Сортировка методом индексов
- •3.7. Быстрая сортировка (алгоритм Хоара)
- •3.8. Вопросы для самоконтроля
- •Сортировка Шелла.
- •Сортировка методом индексов.
- •4. Алгоритмы на графах
- •4.1. Основные понятия теории графов
- •4.2. Структуры данных для представления графов
- •4.3. Алгоритмы обхода вершин графа
- •4.3.1. Обход в глубину
- •4.3.2. Обход в ширину
- •4.4. Поиск остовного дерева минимального веса
- •4.4.1. Алгоритм Дейкстры – Прима
- •4.4.2. Алгоритм Крускала
- •4.5. Алгоритм поиска кратчайшего пути
- •4.6. Вопросы для самоконтроля
- •Структуры данных для представления графов.
- •5. Численные методы
- •5.1. Вычисление значений многочленов
- •5.2. Умножение матриц
- •5.2.1 Стандартный алгоритм умножения матриц
- •5.2.2. Умножение матриц по Винограду
- •5.2.3. Умножение матриц по Штрассену
- •5.3. Вопросы для самоконтроля
- •Стандартный алгоритм умножения матриц.
- •6. Алгоритмы сравнения с образцами
- •6.1. Сравнение строк
- •6.2. Алгоритм Кнута – Морриса – Пратта
- •6.3. Алгоритм Бойера - Мура
- •6.4. Вопросы для самоконтроля
- •7. Вычислительная геометрия
- •7.1. Основные понятия
- •7.2. Векторное произведение векторов
- •7.2.1. Ориентированная площадь треугольника
- •7 .3. Задача о выпуклой оболочке
- •7.3.1. Алгоритм Грэхема
- •7.3.2. Алгоритм Джарвиса
- •7.3.3. Рекурсивный алгоритм
- •7.4. Вопросы для самоконтроля
- •8. Задачи класса np
- •8.1. Примеры np-полных задач
- •8.1.1. Задача о коммивояжере
- •8.1.2. Задача о раскраске графа
- •8.1.3. Раскладка по ящикам
- •8.1.4 Упаковка рюкзака
- •8.1.5. Задача о суммах элементов подмножества
- •8.1.6. Задача о планировании работ
- •8.2. Приближенные эвристические решения nр-полных задач.
- •8.2.1. Жадные приближенные алгоритмы
- •8.2.2. Приближения в задаче коммивояжера
- •8.2.3. Приближения в задаче о раскладке по ящикам
- •8.2.4. Приближения в задаче об упаковке рюкзака
- •8.3. Вопросы для самопроверки
- •Приближения в задаче об упаковке рюкзака.
- •9. Динамическое программирование
- •Часть1--------------------
- •10. Метод ветвей и границ
- •Вопросы к зачету
- •Классификация алгоритмов по виду функции трудоемкости.
- •Приближения в задаче об упаковке рюкзака.
- •Динамическое программирование
- •Метод ветвей и границ. Литература
6.2. Алгоритм Кнута – Морриса – Пратта
Алгоритм Кнута – Морриса – Пратта основан на принципе конечного автомата. При построении конечного автомата для поиска подстроки легко построить переходы из начального состояния в конечное: эти переходы помечены символами подстроки.
Проблема возникает при попытке добавить другие символы, которые не переводят в конечное состояние.
В этом алгоритме состояния помечаются символами, совпадение с которыми в данный момент должно произойти. Из каждого состояния есть 2 перехода: один соответствует успешному сравнению, другой – несовпадению.
Успешное сравнение переводит нас в следующий узел автомата, а в случае несовпадения мы попадаем в предыдущий узел, отвечающий образцу.
При всяком переходе по успешному сравнению в конечном автомате происходит выборка нового символа из текста.
Переходы, отвечающие неудачному сравнению, не приводят к выборке нового символа; вместо этого они используют последний выбранный символ.
Более подробно алгоритм приведен в [2].
6.3. Алгоритм Бойера - Мура
Алгоритм Бойера – Мура осуществляет сравнение с образцом справа налево, а не слева направо. Таким образом можно осуществлять более эффективные прыжки.
Пример 6.3 Исходный текст «РЫБА У РЫБАКА», искомая подстрока «РЫБАК».
Р |
ы |
б |
а |
|
У |
|
Р |
Ы |
Б |
а |
К |
А |
|
|
р |
ы |
б |
а |
к |
|
|
|
|
|
|
|
|
1 проход, 1 сравнение |
|
|
|
|
|
|
р |
ы |
б |
а |
к |
|
|
|
2 проход, 1 сравнение |
|
|
|
|
|
|
|
|
р |
ы |
б |
а |
к |
|
3 проход, 5 сравнений |
|
Итого: |
7 сравнений, слово найдено |
Мы сравниваем последние символы (Пробел и «К») и обнаруживаем несовпадение. Поскольку (Пробел) вообще не входит в образец, то можно сдвинуться в тексте на целых 5 букв (т.е. на длину подстроки).
На втором проходе последние символы текста «Б» и подстроки «К» вновь не совпадает, но буква «Б» – входит в образец. Следовательно, мы можем сдвинуться вправо только на 2 буквы, чтобы совпали буквы «Б» в тексте и в подстроке.
Затем начинаем сравнение справа и обнаруживаем полное совпадение. Таким образом, ответ получен всего за 7 сравнений.
Алгоритм Бойера -Мура обрабатывает образец двумя способами:
вычисляется величина возможного сдвига при несовпадении очередного символа (массив сдвигов);
вычисляется величина прыжка, выделяя в конце образца последовательности символов, уже появлявшихся ранее (массив прыжков).
При несовпадении очередного символа подстроки с очередным символом текста может осуществиться несколько возможностей. Сдвиг в массиве сдвигов может превышать сдвиг в массиве прыжков, а может быть и наоборот. (Совпадение этих величин – простейшая возможная ситуация). О чем говорят эти возможности? Если элемент массива сдвигов больше, то это означает, что несовпадающий символ оказывается ближе к началу, чем повторно появляющиеся завершающие символа строки. Если элемент массива прыжков больше, то повторное появление завершающих символов начинается ближе к началу подстроки, чем несовпадающий символ. В обоих случаях нам следует пользоваться большим из двух сдвигов, поскольку меньший сдвиг опять неизбежно приводит к несовпадению из-за того, что мы знаем о втором значении. (Более подробное описание алгоритма приведено в [2]).