Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка эффективных алгоритмов.doc
Скачиваний:
115
Добавлен:
24.11.2019
Размер:
1.2 Mб
Скачать

6.2. Алгоритм Кнута – Морриса – Пратта

Алгоритм Кнута – Морриса – Пратта основан на принципе конечного автомата. При построении конечного автомата для поиска подстроки легко построить переходы из начального состояния в конечное: эти переходы помечены символами подстроки.

Проблема возникает при попытке добавить другие символы, которые не переводят в конечное состояние.

В этом алгоритме состояния помечаются символами, совпадение с которыми в данный момент должно произойти. Из каждого состояния есть 2 перехода: один соответствует успешному сравнению, другой – несовпадению.

Успешное сравнение переводит нас в следующий узел автомата, а в случае несовпадения мы попадаем в предыдущий узел, отвечающий образцу.

При всяком переходе по успешному сравнению в конечном автомате происходит выборка нового символа из текста.

Переходы, отвечающие неудачному сравнению, не приводят к выборке нового символа; вместо этого они используют последний выбранный символ.

Более подробно алгоритм приведен в [2].

6.3. Алгоритм Бойера - Мура

Алгоритм Бойера – Мура осуществляет сравнение с образцом справа налево, а не слева направо. Таким образом можно осуществлять более эффективные прыжки.

Пример 6.3 Исходный текст «РЫБА У РЫБАКА», искомая подстрока «РЫБАК».

Р

ы

б

а

У

Р

Ы

Б

а

К

А

р

ы

б

а

к

1 проход, 1 сравнение

р

ы

б

а

к

2 проход, 1 сравнение

р

ы

б

а

к

3 проход, 5 сравнений

Итого:

7 сравнений, слово найдено

Мы сравниваем последние символы (Пробел и «К») и обнаруживаем несовпадение. Поскольку (Пробел) вообще не входит в образец, то можно сдвинуться в тексте на целых 5 букв (т.е. на длину подстроки).

На втором проходе последние символы текста «Б» и подстроки «К» вновь не совпадает, но буква «Б» – входит в образец. Следовательно, мы можем сдвинуться вправо только на 2 буквы, чтобы совпали буквы «Б» в тексте и в подстроке.

Затем начинаем сравнение справа и обнаруживаем полное совпадение. Таким образом, ответ получен всего за 7 сравнений.

Алгоритм Бойера -Мура обрабатывает образец двумя способами:

вычисляется величина возможного сдвига при несовпадении очередного символа (массив сдвигов);

вычисляется величина прыжка, выделяя в конце образца последовательности символов, уже появлявшихся ранее (массив прыжков).

При несовпадении очередного символа подстроки с очередным символом текста может осуществиться несколько возможностей. Сдвиг в массиве сдвигов может превышать сдвиг в массиве прыжков, а может быть и наоборот. (Совпадение этих величин – простейшая возможная ситуация). О чем говорят эти возможности? Если элемент массива сдвигов больше, то это означает, что несовпадающий символ оказывается ближе к началу, чем повторно появляющиеся завершающие символа строки. Если элемент массива прыжков больше, то повторное появление завершающих символов начинается ближе к началу подстроки, чем несовпадающий символ. В обоих случаях нам следует пользоваться большим из двух сдвигов, поскольку меньший сдвиг опять неизбежно приводит к несовпадению из-за того, что мы знаем о втором значении. (Более подробное описание алгоритма приведено в [2]).