Двусторонний алгоритм — различия между версиями
Heatwave (обсуждение | вклад) (Начало - описание без псевдокода и примера) |
Heatwave (обсуждение | вклад) |
||
Строка 17: | Строка 17: | ||
Иными словами, <math>w</math> встречается по обе стороны границы между <math>u</math> и <math>v</math> и может "залезать" (overflow). Длина повторения в <math>(u, v)</math> называется '''локальным периодом'''; наименьший локальный период записывается как <math>r(u, v)</math>. | Иными словами, <math>w</math> встречается по обе стороны границы между <math>u</math> и <math>v</math> и может "залезать" (overflow). Длина повторения в <math>(u, v)</math> называется '''локальным периодом'''; наименьший локальный период записывается как <math>r(u, v)</math>. | ||
− | Каждое разбиение <math>x</math> на <math>(u, v)</math> имеет как минимум одно повторение. Очевидно, что <math>1 | + | Каждое разбиение <math>x</math> на <math>(u, v)</math> имеет как минимум одно повторение. Очевидно, что <math>1 \ge r(u, v) \ge |x|</math> |
Разбиение x на <math>(u, v)</math> такое, что <math>r(u, v) = per(x)</math> называется '''критическим разбиением''' <math>x</math>. | Разбиение x на <math>(u, v)</math> такое, что <math>r(u, v) = per(x)</math> называется '''критическим разбиением''' <math>x</math>. | ||
}} | }} | ||
Строка 27: | Строка 27: | ||
Такие действия приводят к квадратичной работе алгоритма в худшем случае, но этого можно избежать запоминанием префикса: когда производится сдвиг длиной <math>per(x)</math>, длина совпадающего префикса образца в начале "окна" (а именно <math>m - per(x)</math>) после сдвига запоминается, чтобы не просматривать ее заново при следующем проходе. | Такие действия приводят к квадратичной работе алгоритма в худшем случае, но этого можно избежать запоминанием префикса: когда производится сдвиг длиной <math>per(x)</math>, длина совпадающего префикса образца в начале "окна" (а именно <math>m - per(x)</math>) после сдвига запоминается, чтобы не просматривать ее заново при следующем проходе. | ||
Фаза поиска может быть выполнена за время <math>O(n)</math>. | Фаза поиска может быть выполнена за время <math>O(n)</math>. | ||
− | Двусторонний алгоритм производит <math>2n - m</math> сравнений символов в худшем случае; вариация этого алгоритма от | + | Двусторонний алгоритм производит <math>2n - m</math> сравнений символов в худшем случае; вариация этого алгоритма от Бреслауэра (Breslauer) выполняет менее <math>2n - m</math> сравнений и использует константное количество памяти. |
==Псевдокод== | ==Псевдокод== |
Версия 11:51, 10 июня 2015
Двусторонний алгоритм (англ. Two Way algorithm) — алгоритм поиска подстроки в строке.
Характерные черты
- требует упорядоченный алфавит
- этап предобработки занимает времени и константное количество памяти
- этап поиска за время
- в худшем случае производится сравнений символов
Описание алгоритма
Образец
разбивается на две части и так, что . Затем фаза поиска в двустороннем алгоритме состоит в сравнении символов слева направо, и затем, если на этом первом этапе не происходит несовпадений, в сравнении символов справа налево (второй этап). Фаза предобработки, таким образом, заключается в поиске подходящего разбиения .Определение: |
Пусть
Иными словами, встречается по обе стороны границы между и и может "залезать" (overflow). Длина повторения в называется локальным периодом; наименьший локальный период записывается как .Каждое разбиение Разбиение x на на имеет как минимум одно повторение. Очевидно, что такое, что называется критическим разбиением . | — разбиение . Повторение в — слово такое, что для него выполнены следующие условия:
Если — критическое разбиение , то на позиции в общий и локальный периоды одинаковы. Двусторонний алгоритм находит критическое разбиение такое, что и длина минимальна.
Чтобы найти критическое разбиение мы сперва вычислим — максимальный суффикс в порядке и максимальный суффикс для обратного порядка . Затем выбираются так, что .
Фаза предобработки может быть выполнена за время O(m) и константное количество памяти.
Фаза поиска в двустороннем алгоритме состоит из сравнения символов слева направо и символов справа налево. Когда происходит несовпадение при просмотре -го символа в , производится сдвиг длиной . Когда происходит несовпадение при просмотре , или когда образец встретился в строке, производится сдвиг длиной .
Такие действия приводят к квадратичной работе алгоритма в худшем случае, но этого можно избежать запоминанием префикса: когда производится сдвиг длиной , длина совпадающего префикса образца в начале "окна" (а именно ) после сдвига запоминается, чтобы не просматривать ее заново при следующем проходе.
Фаза поиска может быть выполнена за время .
Двусторонний алгоритм производит сравнений символов в худшем случае; вариация этого алгоритма от Бреслауэра (Breslauer) выполняет менее сравнений и использует константное количество памяти.