Двусторонний алгоритм сопоставления строк - Two-way string-matching algorithm - Wikipedia
Учебный класс | Алгоритм поиска строки |
---|---|
Структура данных | Любой нить с упорядоченным алфавитом |
Худший случай спектакль | На) |
Лучший случай спектакль | На) |
Худший случай космическая сложность | О (1) |
В Информатика, то двусторонний алгоритм сопоставления строк эффективный алгоритм поиска строки что можно рассматривать как комбинацию перспективных Алгоритм Кнута – Морриса – Пратта и обратный ход Алгоритм поиска строки Бойера – Мура. Максим Крошмор и Доминик Перрен изобрели этот алгоритм в 1991 году.[1] Время предварительной обработки линейно зависит от размера иглы. Он имеет линейную производительность в худшем случае при 2n − m сравнениях.[2] У Бреслауэра есть два улучшения с меньшим количеством сравнений: одно с постоянным пространством и сравнениями n + этаж (1 + eps / 2 × (n − m)), другое с log (m) пространством и n + floor ((n − m) / 2) сравнения.[3]
Как и в случае с KMP и BM, алгоритмы используют сдвиги на основе частично повторяющихся периодов в шаблоне. Однако он делает это путем разделения (критического разложения) иглы на две половины, так что при предварительной обработке необходимо запомнить только одно значение.
Алгоритм считается достаточно эффективным в реальных условиях, удобен для кеширования и содержит операции, которые можно заменить библиотечными функциями. Он выбран как glibc (и производный newlib; str-two-way.h) и мусл алгоритм для семейства функций подстроки memmem и strstr.[4][5][6] Однако, как и в случае с наиболее продвинутыми алгоритмами поиска по строкам, существует тенденция к достижению точки безубыточности в размере и стога сена, и иголки, перед которой более эффективна наивная квадратичная (memchr-memcmp) реализация.[7] Glibc предоставляет алгоритм Бреслауэра в обеих формах.[6]
Критическая факторизация
Прежде чем мы определим критическую факторизацию, мы должны определить:[1]
- Факторизация: строка считается факторизованной, если она разделена на две половины. Предположим, что строка Икс разделен на две части (u, v), тогда (u, v) называется факторизацией Икс。
- Период: Период п для строки Икс определяется как такое значение, что для любого целого числа 0 < я ≤ |Икс| - п, Икс[я] = Икс[я + п]. Другими словами, "п это период Икс если две буквы Икс на расстоянии п всегда совпадают ». Минимальный период Икс натуральное число, обозначаемое как р (х).
- А репетиция ш в (u, v) это подстрока Икс такой, что:
- ш суффикс ты или наоборот;
- ш является префиксом v или наоборот;
- Другими словами, ш происходит с обеих сторон от разреза с возможным переливом с обеих сторон. Каждая факторизация тривиально имеет по крайней мере одно повторение, строка ву.[2]
- А местный период это длина повторения в (u, v). Наименьший местный период в (u, v) обозначается как г (и, v). Для любой факторизации 0 < г (и, v) ≤ |Икс|.
- А критическая факторизация это факторизация (u, v) из Икс такой, что г (и, v) = р (х). Для иглы длины м в упорядоченном алфавите, это может быть вычислено в 2м сравнения, вычисляя лексикографически больший из двух упорядоченных максимальных суффиксов, определенных для порядка ≤ и ≥.[6]
Алгоритм
Алгоритм начинается с критической факторизации иглы как шага предварительной обработки. Этот шаг производит индекс (начальную точку) периодической правой половины и период этого растяжения. Вычисление суффикса здесь следует формулировке авторов. В качестве альтернативы его можно вычислить с помощью более простого Алгоритм Дюваля, что медленнее, но также линейно.[8]
Сокращение для инверсии.функция cmp (a, b) если а> б возвращаться 1 если а = б возвращаться 0 если а <б возвращаться -1функция maxsuf (n, rev) l ← len (n) p ← 1 известный в настоящее время период. k ← 1 индекс для периодического тестирования, 0j ← 0 индекс для тестирования maxsuf. больше, чем макс. я ← -1 предлагаемый начальный индекс maxsuf пока j + k если rev cmpv ← -cmpv инвертировать сравнение если cmpv <0 Суффикс (j + k) меньше. Точка - это пока весь префикс. j ← j + k k ← 1 p ← j - i иначе если cmpv = 0 Они такие же - надо идти дальше. если k = p Мы закончили проверку этого участка стр. сбросить k. j ← j + p k ← 1 еще к ← к + 1 еще Суффикс больше. Начни отсюда. i ← j j ← j + 1 p ← 1 k ← 1 возвращаться [i, p]функция cris_fact (n) [idx1, per1] ← maxsuf (n, false) [idx2, per2] ← maxsuf (n, истина) если idx1> idx2 возвращаться [idx1, per1] еще возвращаться [idx2, per2]
Сравнение выполняется сначала для правой части, а затем для левой, если она совпадает. Линейный пропуск времени выполняется с использованием точки.
функция match (n, h) nl ← len (n) hl ← len (h) [l, p] ← cris_fact (n) P ← {} набор спичек. Подберите суффикс. Используйте библиотечную функцию, например memcmp, или напишите свой собственный цикл. если h [0] ... h [l] = h [p] ... h [l + p] P ← {} pos ← 0 s ← 0 СДЕЛАТЬ. По крайней мере, вставьте скип.
Рекомендации
- ^ а б Крошмор, Максим; Перрен, Доминик (1 июля 1991 г.). «Двустороннее сопоставление строк» (PDF). Журнал ACM. 38 (3): 650–674. Дои:10.1145/116825.116845.
- ^ а б «Двусторонний алгоритм».
- ^ Бреслауэр, Дэни (май 1996 г.). «Сохранение сравнений в алгоритме сопоставления строк Крошмора-Перрина». Теоретическая информатика. 158 (1–2): 177–192. Дои:10.1016/0304-3975(95)00068-2.
- ^ "мусл / SRC / строка / memmem.c". Получено 23 ноября 2019.
- ^ "новая библиотека / libc / строка / memmem.c". Получено 23 ноября 2019.
- ^ а б c "glibc / строка / str-two-way.h".
- ^ "Эрик Блейк - Re: PATCH] Повышение производительности меммема". Список рассылки Newlib.
- ^ Адамчик, Збигнев; Риттер, Войцех (май 2013 г.). «Замечание о простом вычислении максимального суффикса строки». Журнал дискретных алгоритмов. 20: 61–64. Дои:10.1016 / j.jda.2013.03.002.