<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>https://nerc.itmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=178.178.1.62&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="https://nerc.itmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=178.178.1.62&amp;*"/>
		<link rel="alternate" type="text/html" href="https://nerc.itmo.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/178.178.1.62"/>
		<updated>2026-09-15T06:52:11Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>https://nerc.itmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8_%D0%B2_%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B5_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%85%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F._%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A0%D0%B0%D0%B1%D0%B8%D0%BD%D0%B0-%D0%9A%D0%B0%D1%80%D0%BF%D0%B0&amp;diff=19914</id>
		<title>Поиск подстроки в строке с использованием хеширования. Алгоритм Рабина-Карпа</title>
		<link rel="alternate" type="text/html" href="https://nerc.itmo.ru/wiki/index.php?title=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8_%D0%B2_%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B5_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%85%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F._%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A0%D0%B0%D0%B1%D0%B8%D0%BD%D0%B0-%D0%9A%D0%B0%D1%80%D0%BF%D0%B0&amp;diff=19914"/>
				<updated>2012-03-24T18:45:12Z</updated>
		
		<summary type="html">&lt;p&gt;178.178.1.62: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм Рабина — Карпа — это алгоритм поиска подстроки в строке, используя хеширование.&lt;br /&gt;
&lt;br /&gt;
===Метод хеширования===&lt;br /&gt;
&lt;br /&gt;
Выберем полиномиальный хеш - &amp;lt;tex&amp;gt;hash(s[1..n]) = (p^{n - 1} s[1] + ... + p^{0} s[n])&amp;lt;/tex&amp;gt; mod &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; - это некоторое простое число, а &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; - некоторое большое число, чтобы было меньше коллизий (обычно берётся &amp;lt;tex&amp;gt;2^{32}&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;2^{64}&amp;lt;/tex&amp;gt;, чтобы модуль брался автоматически - при переполнении типов;). Заметим, что если 2 строчки имеют одинаковый хэш, то они в большинстве таких случаев равны.&lt;br /&gt;
&lt;br /&gt;
Давайте научимся при удалении первого символа строки и добавлении символа в конец считать хеш новой строки при помощи хеша изначальной строки за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;hash(s[i + 1..i + m - 1]) = hash(s[i..i + m - 1]) - p^{m - 1} s[i]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;hash(s[i + 1..i + m]) = p \cdot hash(s[i + 1..i + m - 1]) + s[i + m]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Получается : &amp;lt;tex&amp;gt;hash(s[i + 1..i + m]) = p \cdot hash(s[i..i + m - 1]) - p^{m} s[i] + s[i + m]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
&lt;br /&gt;
У нас есть шаблон - &amp;lt;tex&amp;gt;p[1..m]&amp;lt;/tex&amp;gt;. У нас есть строка - &amp;lt;tex&amp;gt;s[1..n]&amp;lt;/tex&amp;gt;. Мы хотим найти все вхождения шаблона в строку.&lt;br /&gt;
&lt;br /&gt;
Давайте посчитаем &amp;lt;tex&amp;gt;hash(s[1..m])&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;hash(p[1..m])&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
И для &amp;lt;tex&amp;gt;i \in [1..n - m + 1]&amp;lt;/tex&amp;gt; считаем &amp;lt;tex&amp;gt;hash(s[i..i + m - 1]&amp;lt;/tex&amp;gt; - сравниваем с &amp;lt;tex&amp;gt;hash(p[1..m])&amp;lt;/tex&amp;gt;. Если они получаются равными - то мы считаем, что подстрока &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; входит в строку &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; (начиная с позиции &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;;) или мы проверяем, что подстрока является шаблоном, для этого выберем случайные символы из строк и сравним их.&lt;br /&gt;
&lt;br /&gt;
Следует предподсчитать &amp;lt;tex&amp;gt;p^{m}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Псевдо-код:&lt;br /&gt;
  '''1:''' function RabinKarp(string s[1..n], string p[1..m])&lt;br /&gt;
  '''2:'''   hp := hash(p[1..m])&lt;br /&gt;
  '''3:'''   h := hash(s[1..m])&lt;br /&gt;
  '''4:'''   for i from 1 to (n - m + 1)&lt;br /&gt;
  '''5:'''       if h = hp&lt;br /&gt;
  '''6:'''          answer.add(i)&lt;br /&gt;
  '''7:'''       h := p &amp;lt;tex&amp;gt;\cdot&amp;lt;/tex&amp;gt; h - &amp;lt;tex&amp;gt;p^{m}&amp;lt;/tex&amp;gt;s[i] + s[i + m]&lt;br /&gt;
  '''8:'''   if ans.size = 0 &lt;br /&gt;
  '''9:'''       return not found&lt;br /&gt;
  '''10:'''  else&lt;br /&gt;
  '''11:'''      return answer&lt;br /&gt;
&lt;br /&gt;
7 строка была получена с помощью быстрого пересчёта хеша. Мы считаем, что &amp;lt;tex&amp;gt;s[n + 1]&amp;lt;/tex&amp;gt; - пустой символ.&lt;br /&gt;
&lt;br /&gt;
Посчитаем время работы.&lt;br /&gt;
&lt;br /&gt;
Изначальный подсчёт хешей - &amp;lt;tex&amp;gt;O(m)&amp;lt;/tex&amp;gt;. В цикле всего &amp;lt;tex&amp;gt;n - m + 1&amp;lt;/tex&amp;gt; итераций - каждая выполняется за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;. Итого - &amp;lt;tex&amp;gt;O(n + m)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. — 2-е изд. — М.: Издательский дом «Вильямс», 2007. — С. 1296.&lt;/div&gt;</summary>
		<author><name>178.178.1.62</name></author>	</entry>

	<entry>
		<id>https://nerc.itmo.ru/wiki/index.php?title=%D0%9D%D0%B0%D0%B8%D0%B2%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8_%D0%B2_%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B5&amp;diff=19894</id>
		<title>Наивный алгоритм поиска подстроки в строке</title>
		<link rel="alternate" type="text/html" href="https://nerc.itmo.ru/wiki/index.php?title=%D0%9D%D0%B0%D0%B8%D0%B2%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA%D0%B0_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8_%D0%B2_%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B5&amp;diff=19894"/>
				<updated>2012-03-24T17:54:21Z</updated>
		
		<summary type="html">&lt;p&gt;178.178.1.62: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Постановка задачи==&lt;br /&gt;
Имеются строки &amp;lt;tex&amp;gt;T[1 .. n]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P[1 .. m]&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;\ge&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; и элементы этих строк  &amp;lt;tex&amp;gt;-&amp;lt;/tex&amp;gt; символы из конечного алфавита &amp;lt;tex&amp;gt; \sum &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;s&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt; 0 \le s \le n-m&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T[s + 1 .. s + m]&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;P[1..m]&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;T&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;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
В наивном алгоритме поиск всех допустимых сдвигов производится с помощью цикла, в котором проверяется условие &amp;lt;tex&amp;gt;T[s + 1 .. s + m]&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;P[1..m]&amp;lt;/tex&amp;gt; для каждого из &amp;lt;tex&amp;gt; n-m+1&amp;lt;/tex&amp;gt;  возможных значений &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
&lt;br /&gt;
 '''Naive_String_Matcher''' (&amp;lt;tex&amp;gt;T,P&amp;lt;/tex&amp;gt;)&lt;br /&gt;
 &amp;lt;tex&amp;gt;n \leftarrow length[T]&amp;lt;/tex&amp;gt;&lt;br /&gt;
 &amp;lt;tex&amp;gt;m \leftarrow length[P]&amp;lt;/tex&amp;gt;&lt;br /&gt;
 '''for''' &amp;lt;tex&amp;gt;s \leftarrow 0&amp;lt;/tex&amp;gt; to &amp;lt;tex&amp;gt;n - m&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''do if''' &amp;lt;tex&amp;gt;T[s + 1 .. s + m]&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;P[1..m]&amp;lt;/tex&amp;gt;&lt;br /&gt;
           '''then''' print()    &lt;br /&gt;
&lt;br /&gt;
==Время работы==&lt;br /&gt;
Алгоритм работает за &amp;lt;tex&amp;gt;O(m * (n - m))&amp;lt;/tex&amp;gt;, в худшем случае &amp;lt;tex&amp;gt; m = n / 2 &amp;lt;/tex&amp;gt;, что дает &amp;lt;tex&amp;gt; O(n^2/4) = O(n^2) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* ''Кормен Т., Лейзерсон Ч., Ривест Р.'' Алгоритмы: построение и анализ.[http://wmate.ru/ebooks/?dl=380&amp;amp;mirror=1] — 2-е изд. — М.: Издательский дом «Вильямс», 2007. — С. 1296.&lt;/div&gt;</summary>
		<author><name>178.178.1.62</name></author>	</entry>

	</feed>