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