Двусторонний алгоритм — различия между версиями
Heatwave (обсуждение | вклад) (Исправления) |
Heatwave (обсуждение | вклад) (→См. также) |
||
Строка 91: | Строка 91: | ||
[[Категория:Алгоритмы и структуры данных]] | [[Категория:Алгоритмы и структуры данных]] | ||
[[Категория:Поиск подстроки в строке]] | [[Категория:Поиск подстроки в строке]] | ||
+ | [[Категория:Точный поиск]] |
Версия 22:33, 15 июня 2015
Двусторонний алгоритм (англ. Two Way algorithm) — алгоритм поиска подстроки в строке.
Характерные черты
- требует упорядоченный алфавит,
- этап предобработки занимает времени и константное количество памяти,
- этап поиска за время , где m — длина образца, а n — длина текста.
Описание алгоритма
Строка
разбивается на две части и так, что . Затем фаза поиска в двустороннем алгоритме состоит в сравнении символов слева направо, и затем, если на первом этапе не происходит несовпадений, в сравнении символов справа налево (второй этап). Фаза предобработки, таким образом, заключается в поиске подходящего разбиения .Определение: |
— разбиение строки , если . |
Определение: |
Пусть
| — разбиение . Повторение в — слово такое, что для него выполнены следующие условия:
Определение: |
Длина повторения в | называется локальным периодом; наименьший локальный период записывается как . Каждое разбиение на имеет как минимум одно повторение. Очевидно, что
Определение: |
Разбиение | на такое, что называется критическим разбиением .
Если — критическое разбиение , то на позиции в общий и локальный периоды одинаковы. Двусторонний алгоритм находит критическое разбиение такое, что и длина минимальна.
Чтобы найти критическое разбиение мы сперва вычислим — максимальный суффикс в лексикографическом порядке, характерном для заданного алфавита и максимальный суффикс для обратного лексикографического порядка . Затем выбираются так, что .
Фаза поиска в двустороннем алгоритме состоит из сравнения символов
слева направо и символов справа налево. Когда происходит несовпадение при просмотре -го символа в , производится сдвиг длиной . Когда происходит несовпадение при просмотре или когда образец встретился в строке, производится сдвиг длиной . Такие действия приводят к квадратичной работе алгоритма в худшем случае, но этого можно избежать запоминанием префикса: когда производится сдвиг длиной , длина совпадающего префикса образца в начале "окна" (а именно ) после сдвига запоминается, чтобы не просматривать ее заново при следующем проходе.Псевдокод
function twoWaySearch(String pattern, String text): n = pattern.lengthlen1, p1 maxSuffix(pattern, ) len2, p2 maxSuffix(pattern, ) if len1 len2 len = len1 p = p1 else len = len2 p = p2 occurences = pos 0 memPrefix 0 if len < n/2 and pattern[1 len] суффикс pattern[len + 1 len + p] while pos + n text.length i (l, memPrefix) + 1 while i n and pattern[i] text[pos + i] i++ if i n pos pos + (i len, memPrefix p 1) memPrefix 0 else j l while j memPrefix and pattern[j] text[pos + j] j-- if j memPrefix pos occurences pos pos p memPrefix n p else q (len, n len) 1 while pos + n text.length i len + 1 while i n and pattern[i] text[pos i] i++ if i n pos pos i len else j len while j 0 and pattern[j] text[pos j] j-- if j 0 pos occurences pos pos q return occurences