Довідка та теорія
Кнут-Морріс-Пратт (КМП) шукає патерн усередині тексту
за O(n+m) часу, де n — довжина
тексту, а m — довжина патерну.
Функція відмови
Для кожної позиції q патерну
fail[q] — це довжина найдовшого власного префікса
P[0..q], що є також суфіксом. Вона обчислюється
зіставленням патерну з самим собою за O(m) часу.
Сканування
Ведіть один курсор i по тексту й курсор
q по патерну. На збігу обидва просуваються. За
розбіжності з q > 0 покладіть
q = fail[q−1] — патерн ковзає вперед, поки
i стоїть. Курсор тексту ніколи не рухається
назад.
Чому лінійний
Кожен крок або просуває i, або зменшує
q. Оскільки q може зростати стільки ж
разів, скільки просувається i, загальна робота —
O(n+m).
Де застосовується
Пошук у редакторі, grep, сканування сигнатур
систем виявлення вторгнень і біоінформатика використовують
КМП або споріднені лінійні зіставлювачі.
Поширені запитання
Що таке алгоритм КМП?
Алгоритм Кнута-Морріса-Пратта знаходить усі входження патерну в тексті за лінійний час O(n+m), наперед обчислюючи функцію відмови, тож курсор тексту ніколи не рухається назад.
Що таке функція відмови?
Функція відмови (префіксна функція) для кожної позиції патерну зберігає довжину найдовшого власного префікса, що є також суфіксом. Вона підказує алгоритму, наскільки зсунути патерн після розбіжності.
Чому курсор тексту ніколи не рухається назад?
За розбіжності функція відмови повідомляє КМП, яка частина патерну вже збіглася як префікс, тож алгоритм зсуває патерн замість того, щоб відмотувати текст. Кожен символ тексту перевіряється не більше сталого числа разів.
Чому КМП швидший за наївний пошук?
Наївний пошук може повторно порівнювати символи після кожного зсуву, що дає O(n·m) у найгіршому випадку. КМП повторно використовує інформацію з попередніх порівнянь, досягаючи O(n+m).
Як обчислюється функція відмови?
Її будують, зіставляючи патерн із самим собою: вказівник стежить за поточною довжиною префікса, подовжуючи її на збігу та відкочуючись через попередні значення відмови на розбіжності, усе за O(m) часу.
Яка складність за часом і пам'яттю?
КМП працює за O(n+m) часу, де n — довжина тексту, а m — довжина патерну, і використовує O(m) додаткової пам'яті для таблиці відмови.
Чи може КМП знаходити перекривні входження?
Так. Після повного збігу він використовує значення відмови останньої позиції патерну, щоб продовжити, тож перекривні входження, як-от AA в AAAA, усі звітуються.
Де застосовується КМП?
Текстові редактори, пошук на кшталт grep, виявлення вторгнень, біоінформатика та інспекція мережевих пакетів використовують КМП або споріднені лінійні алгоритми зіставлення.
Як КМП порівнюється з алгоритмом Бойєра-Мура?
Бойєр-Мур сканує патерн справа наліво й може пропускати великі ділянки, часто швидший на практиці, тоді як КМП гарантує строгу лінійну межу й ніколи не рухає курсор тексту назад.
Що відбувається, якщо патерн порожній?
Порожній патерн за домовленістю збігається на кожній позиції. Ця симуляція очікує непорожній патерн, не довший за текст, для змістовного пошуку.