Двусторонний алгоритм сопоставления строк - 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 индекс для периодического тестирования, 0     j ← 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. ^ а б Крошмор, Максим; Перрен, Доминик (1 июля 1991 г.). «Двустороннее сопоставление строк» (PDF). Журнал ACM. 38 (3): 650–674. Дои:10.1145/116825.116845.
  2. ^ а б «Двусторонний алгоритм».
  3. ^ Бреслауэр, Дэни (май 1996 г.). «Сохранение сравнений в алгоритме сопоставления строк Крошмора-Перрина». Теоретическая информатика. 158 (1–2): 177–192. Дои:10.1016/0304-3975(95)00068-2.
  4. ^ "мусл / SRC / строка / memmem.c". Получено 23 ноября 2019.
  5. ^ "новая библиотека / libc / строка / memmem.c". Получено 23 ноября 2019.
  6. ^ а б c "glibc / строка / str-two-way.h".
  7. ^ "Эрик Блейк - Re: PATCH] Повышение производительности меммема". Список рассылки Newlib.
  8. ^ Адамчик, Збигнев; Риттер, Войцех (май 2013 г.). «Замечание о простом вычислении максимального суффикса строки». Журнал дискретных алгоритмов. 20: 61–64. Дои:10.1016 / j.jda.2013.03.002.