Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

572 Глава 12. Последовательности и динамическое программирование

Рисунок 12.7: алгоритм соответствия образца KMP. Функция неудачи f для этого образца дана в Примере 12.5. Алгоритм выполняет 19 характеров compar-isons, которые обозначены с числовыми этикетками.

В рисунке 12.7 мы иллюстрируем выполнение образца KMP, соответствующего algo-rithm на тех же самых строках ввода как в Примере 12.4. Отметьте использование функции неудачи, чтобы избежать делать заново одно из сравнений между характером кусочка - крачка и характером текста. Также обратите внимание на то, что алгоритм выполняет меньше полных сравнений, чем пробег алгоритма «в лоб» на тех же самых последовательностях (рисунок 12.3).

Работа

Исключая вычисление функции неудачи, продолжительность KMP

алгоритм ясно пропорционален числу повторений в то время как петля. Для

польза анализа, давайте определим k = i-j. Интуитивно, k - общая сумма который

образец P был перемещен относительно текста T. Отметьте это повсюду

выполнение алгоритма, у нас есть k£ n. Один из следующих трех случаев происходит

при каждом повторении петли.

• Если T [я] = P [j], то я увеличиваюсь на 1, и k, не изменяюсь, с тех пор j также

увеличения 1.

• Если T [я] = P [j] и j> 0, то я не изменяюсь и k, увеличиваюсь на по крайней мере 1,

с тех пор, в этом случае, k изменяется от меня- j мне- f (j- 1), который является добавлением j- f (j- 1), который является положительным потому что f (j- 1) <j.

• Если T [я] = P [j] и j = 0, то я увеличиваюсь на 1 и k, увеличиваюсь на 1, с тех пор j

не изменяется.

Таким образом, при каждом повторении петли, или я или k увеличиваемся на по крайней мере 1 (возможно оба); следовательно, общее количество повторений, в то время как петля в алгоритме соответствия образца KMP самое большее 2n. Конечно, достижение этого связало, предполагает, что мы уже вычислили функцию неудачи для P.

12.3. Алгоритмы соответствия образца 573

Строительство функции неудачи KMP

Чтобы построить функцию неудачи, мы используем метод, показанный в Кодовом Фрагменте 12.7, который является процессом «самонастройки», довольно подобным алгоритму KMPMatch. Мы сравниваем образец с собой как в алгоритме KMP. Каждый раз у нас есть два знака, которые соответствуют, мы устанавливаем f (i) = j + 1. Отметьте это, так как у нас есть i> j повсюду

выполнение алгоритма, f (j- 1) всегда определяется, когда мы должны использовать его.

Алгоритм KMPFailureFunction (P):

Вход: Натяните P (образец) с m Продукцией знаков: функция неудачи f для P, который наносит на карту j к длине самого длинного

префикс P, который является суффиксом P [1.. j]

i¬1

j¬0 f (0)¬ 0

в то время как я <m делаю

если P [j] = P [я] тогда

мы соответствовали j + 1 знак

f (i)¬ j + 1 я¬ i+1 j¬ j+1

еще, если j> 0 тогда

j индексы сразу после префикса P, который должен соответствовать

j¬ f (j- 1)

еще

у нас нет матча здесь

f (i)¬ 0 я¬ i+1

Кодовый Фрагмент 12.7: Вычисление функции неудачи используется в алгоритме соответствия образца KMP. Отметьте, как алгоритм использует предыдущие ценности функции неудачи, чтобы эффективно вычислить новые ценности.

Алгоритм KMPFailureFunction управляет в O (m) временем. Его анализ походит на анализ алгоритма KMPMatch. Таким образом мы имеем:

Суждение 12.6: Knuth-Morris-Pratt алгоритм выполняет образец, соответствующий на текстовой строке длины n и последовательности образца длины m в O (n + m) время.

C ++ внедрение алгоритма соответствия образца KMP, основанного на векторе STL, показывают в Кодовом Фрагменте 12.8.

574