<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=91.207.170.129&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=91.207.170.129&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/91.207.170.129"/>
		<updated>2026-04-22T18:40:37Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9A%D0%BD%D1%83%D1%82%D0%B0-%D0%9C%D0%BE%D1%80%D1%80%D0%B8%D1%81%D0%B0-%D0%9F%D1%80%D0%B0%D1%82%D1%82%D0%B0&amp;diff=79476</id>
		<title>Алгоритм Кнута-Морриса-Пратта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9A%D0%BD%D1%83%D1%82%D0%B0-%D0%9C%D0%BE%D1%80%D1%80%D0%B8%D1%81%D0%B0-%D0%9F%D1%80%D0%B0%D1%82%D1%82%D0%B0&amp;diff=79476"/>
				<updated>2021-01-21T01:00:43Z</updated>
		
		<summary type="html">&lt;p&gt;91.207.170.129: /* Оценка по памяти */ логическая ошибка и как следствие было неверное обоснование  для оценки&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Алгоритм Кнута — Морриса — Пратта''' (англ. ''Knuth–Morris–Pratt algorithm'') — алгоритм [[Наивный алгоритм поиска подстроки в строке#Постановка задачи|поиска подстроки в строке]].&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Дана цепочка &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и образец &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Требуется найти все позиции, начиная с которых &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; входит в &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Построим строку &amp;lt;tex&amp;gt;S = P\#T&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\#&amp;lt;/tex&amp;gt; — любой символ, не входящий в алфавит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Посчитаем на ней значение [[Префикс-функция|префикс-функции]] &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt;. Благодаря разделительному символу &amp;lt;tex&amp;gt;\#&amp;lt;/tex&amp;gt;, выполняется &amp;lt;tex&amp;gt;\forall i: p[i] \leqslant |P|&amp;lt;/tex&amp;gt;. Заметим, что по определению [[Префикс-функция|префикс-функции]] при &amp;lt;tex&amp;gt;i &amp;gt; |P|&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p[i] = |P|&amp;lt;/tex&amp;gt; подстроки длины &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начинающиеся с позиций &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i - |P| + 1&amp;lt;/tex&amp;gt;, совпадают. Соберем все такие позиции &amp;lt;tex&amp;gt;i - |P| + 1&amp;lt;/tex&amp;gt; строки &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, вычтем из каждой позиции &amp;lt;tex&amp;gt;|P| + 1&amp;lt;/tex&amp;gt;, это и будет ответ. Другими словами, если в какой-то позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; выполняется условие &amp;lt;tex&amp;gt;p[i]=|P|&amp;lt;/tex&amp;gt;, то в этой позиции начинается очередное вхождение образца в цепочку.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:kmp_pict2.png|640px]]&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
 '''int'''[] kmp('''string''' P, '''string''' T):&lt;br /&gt;
    '''int''' pl = P.length&lt;br /&gt;
    '''int''' tl = T.length&lt;br /&gt;
    '''int'''[] answer&lt;br /&gt;
    '''int'''[] p = [[Префикс-функция#Эффективный_алгоритм|prefixFunction(P + &amp;quot;#&amp;quot; + T)]]&lt;br /&gt;
    '''int''' count = 0&lt;br /&gt;
    '''for''' i = 0 .. tl - 1&lt;br /&gt;
       '''if''' p[pl + i + 1] == pl&lt;br /&gt;
          answer[count++] = i&lt;br /&gt;
    '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Время работы==&lt;br /&gt;
Префикс-функция от строки &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; строится за &amp;lt;tex&amp;gt;O(S) = O(P + T)&amp;lt;/tex&amp;gt;. Проход цикла по строке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; содержит &amp;lt;tex&amp;gt;O(T)&amp;lt;/tex&amp;gt; итераций. Итого, время работы алгоритма оценивается как &amp;lt;tex&amp;gt;O(P + T)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Оценка по памяти==&lt;br /&gt;
Предложенная реализация имеет оценку по памяти &amp;lt;tex&amp;gt;O(P+T)&amp;lt;/tex&amp;gt;. Оценки &amp;lt;tex&amp;gt;O(P)&amp;lt;/tex&amp;gt; можно добиться за счет запоминания значений префикс-функции для позиций в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, меньших &amp;lt;tex&amp;gt;|P| + 1&amp;lt;/tex&amp;gt; (то есть до начала цепочки &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;). Это возможно, так как значение префикс-функции не может превысить длину образца, благодаря разделительному символу &amp;lt;tex&amp;gt;\#&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Замечание==&lt;br /&gt;
Вместо [[Префикс-функция|префикс-функции]] в алгоритме Кнута-Морриса-Пратта можно использовать [[Z-функция|Z-функцию]]. Оценки времени работы и памяти при этом не изменятся.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм Ахо-Корасик|Алгоритм Ахо-Корасик]]&lt;br /&gt;
*[[Алгоритм Бойера-Мура|Алгоритм Бойера-Мура]]&lt;br /&gt;
*[[Алгоритм Колусси|Алгоритм Колусси]]&lt;br /&gt;
*[[Префикс-функция|Префикс-функция]]&lt;br /&gt;
*[[Z-функция|Z-функция]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[[wikipedia:en:Knuth–Morris–Pratt algorithm | Wikipedia {{---}} Knuth–Morris–Pratt algorithm]]&lt;br /&gt;
*[[wikipedia:ru:Алгоритм Кнута — Морриса — Пратта | Википедия {{---}} Алгоритм Кнута — Морриса — Пратта]]&lt;br /&gt;
*Кормен, Т., Лейзерсон, Ч., Ривест, Р., Штайн — Алгоритмы: построение и анализ / пер. с англ. — изд. 2-е — М.: Издательский дом «Вильямс», 2009. — с.1036. — ISBN 978-5-8459-0857-5.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Поиск подстроки в строке]]&lt;br /&gt;
[[Категория:Точный поиск]]&lt;/div&gt;</summary>
		<author><name>91.207.170.129</name></author>	</entry>

	</feed>