В информатике алгоритмы поиска строк , иногда называемые алгоритмами сопоставления строк , представляют собой важный класс строковых алгоритмов , которые пытаются найти место, где одна или несколько строк (также называемых шаблонами) находятся внутри более крупной строки или текста.
Базовый пример поиска строк — это когда шаблон и искомый текст представляют собой массивы элементов алфавита ( конечного множества ) Σ. Σ может быть алфавитом человеческого языка, например, буквы от A до Z , а другие приложения могут использовать двоичный алфавит (Σ = {0,1}) или алфавит ДНК (Σ = {A,C,G,T}). в биоинформатике .
На практике на метод допустимого алгоритма поиска строк может влиять кодирование строки. В частности, если используется кодировка переменной ширины , поиск N- го символа может занять больше времени, возможно, потребуется время , пропорциональное N. Это может значительно замедлить работу некоторых алгоритмов поиска. Одним из многих возможных решений является поиск последовательности кодовых единиц, но это может привести к ложным совпадениям, если только кодирование специально не предназначено для предотвращения этого. [ нужна цитата ]
Самый простой случай поиска строк включает в себя одну (часто очень длинную) строку, иногда называемую haystack , и одну (часто очень короткую) строку, иногда называемую иголкой . Цель состоит в том, чтобы найти одно или несколько вхождений иглы в стоге сена. Например, можно выполнить поиск с точностью до:
Некоторые книги нужно попробовать, другие — проглотить, а некоторые — пережевать и переварить.
Можно запросить первое вхождение слова «to», которое является четвертым словом; или все вхождения, которых 3; или последнее, то есть пятое слово с конца.
Однако очень часто добавляются различные ограничения. Например, можно захотеть сопоставить «иглу» только в том случае, если она состоит из одного (или нескольких) полных слов - возможно, определяемых как отсутствие других букв, непосредственно прилегающих с обеих сторон. В этом случае поиск по словам «hew» или «low» для приведенного выше примера предложения не будет успешным, даже если эти литеральные строки действительно встречаются.
Другой распространенный пример включает «нормализацию». Во многих случаях поиск такой фразы, как «быть», должен быть успешным даже в тех местах, где между «быть» и «быть» есть что-то еще:
Многие системы символов включают символы, которые являются синонимами (по крайней мере, для некоторых целей):
Наконец, для строк, представляющих естественный язык, задействуются аспекты самого языка. Например, можно захотеть найти все вхождения «слова», несмотря на то, что оно имеет альтернативные варианты написания, префиксы или суффиксы и т. д.
Другой, более сложный тип поиска — это поиск по регулярным выражениям , при котором пользователь создает шаблон символов или других символов, и любое совпадение с шаблоном должно выполнять поиск. Например, чтобы уловить как американское английское слово «color», так и его британский эквивалент «color», вместо поиска двух разных литеральных строк можно использовать регулярное выражение, например:
цвет
где "?" обычно делает предыдущий символ («u») необязательным.
В этой статье в основном обсуждаются алгоритмы для более простых видов поиска строк.
Аналогичная проблема, возникшая в области биоинформатики и геномики, — максимально точное сопоставление (MEM). [1] Учитывая две строки, MEM представляют собой общие подстроки, которые нельзя расширить влево или вправо, не вызывая несоответствия. [2]
Простой и неэффективный способ увидеть, где одна строка находится внутри другой, — это проверять каждый индекс один за другим. Сначала мы видим, существует ли копия иглы, начинающаяся с первого символа стога сена; если нет, мы смотрим, есть ли копия иглы, начинающаяся со второго символа стога сена, и так далее. В обычном случае нам нужно посмотреть только на один или два символа для каждой неправильной позиции, чтобы увидеть, что это неправильная позиция, поэтому в среднем случае это занимает O ( n + m ) шагов, где n — длина стог сена и m – длина иглы; но в худшем случае поиск строки типа «aaaab» в строке типа «aaaaaaaaab» занимает O ( nm )
В этом подходе возврата назад можно избежать за счет построения детерминированного конечного автомата (DFA), который распознает сохраненную строку поиска. Их создание дорого (обычно они создаются с использованием конструкции powerset ), но их очень быстро использовать. Например, DFA , показанный справа, распознает слово «МАМА». На практике этот подход часто обобщается для поиска произвольных регулярных выражений .
Кнут-Моррис-Пратт вычисляет ДКА , который распознает входные данные со строкой, которую нужно найти в качестве суффикса, Бойер-Мур начинает поиск с конца иглы, поэтому обычно на каждом шаге он может перескакивать вперед на всю длину иглы. Баеза-Йейтс отслеживает, были ли предыдущие символы j префиксом строки поиска, и поэтому может быть адаптирован для поиска нечеткой строки . Алгоритм битового ввода представляет собой применение подхода Баеза-Йейтса.
Алгоритмы более быстрого поиска предварительно обрабатывают текст. После построения индекса подстроки , например суффиксного дерева или суффиксного массива , можно быстро найти вхождения шаблона. Например, суффиксное дерево может быть построено во времени, и все вхождения шаблона могут быть найдены во времени при условии, что алфавит имеет постоянный размер и все внутренние узлы суффиксного дерева знают, какие листья находятся под ними. Последнее можно выполнить, запустив алгоритм DFS из корня суффиксного дерева.
Некоторые методы поиска, например триграммный поиск , предназначены для поиска показателя «близости» между строкой поиска и текстом, а не «совпадения/несовпадения». Иногда их называют «нечеткими» поисками .
Различные алгоритмы можно классифицировать по количеству используемых шаблонов.
В следующей компиляции m — это длина шаблона, n — длина текста, доступного для поиска, а k = |Σ| размер алфавита.
Алгоритм поиска строк Бойера-Мура был стандартным эталоном в практической литературе по поиску строк. [8]
В следующей компиляции M — длина самого длинного шаблона, m — их общая длина, n — длина текста, доступного для поиска, o — количество вхождений.
Естественно, что в этом случае закономерности невозможно перечислить конечно. Обычно они представлены регулярной грамматикой или регулярным выражением .
Возможны и другие подходы к классификации. Один из наиболее распространенных использует предварительную обработку в качестве основного критерия.
Другой классифицирует алгоритмы по их стратегии сопоставления: [12]
{{citation}}
: Внешняя ссылка |surname2=
( помощь )CS1 maint: numeric names: authors list (link)