Мне нужен эффективный алгоритм (или библиотека), который я могу использовать в Java для поиска подстрок в строке.
Что я хотел бы сделать:
Учитывая входную строку - INSTR:
"BCDEFGH"
И набор строк-кандидатов - CAND:
"AB", "CDE", "FG", "H", "IJ"
Найдите строки CAND, которые соответствуют подстрокам в INSTR
В этом примере я бы соответствовал "CDE", "FG" и "H" (но не "AB" и "IJ" )
Может быть много тысяч строк-кандидатов (в CAND), но, что более важно, я буду выполнять этот поиск много миллионов раз, поэтому мне нужно, чтобы он был FAST.
Я хотел бы работать с массивами char. Кроме того, меня не интересуют архитектурные решения, такие как распространение поиска - всего лишь самая эффективная функция/алгоритм для локального решения.
Кроме того, все строки в CAND и INSTR будут относительно небольшими (< 50 символов), то есть целевая строка INSTR НЕ длинна относительно строк-кандидатов.
Обновить. Я должен был упомянуть, набор строк CAND является инвариантным по всем значениям INSTR.
Обновить Мне нужно только знать, что было совпадение - и мне не нужно знать, что такое матч.
Окончательное обновление Я решил попробовать AhoCorsick и Rabin-Karp из-за простоты реализации. Поскольку у меня есть шаблоны переменной длины, я использовал модифицированный Rabin-Karp, который хэширует первые n символов каждого шаблона, где n - длина самого маленького шаблона, тогда N - это длина моего поискового окна подстроки. Для Ахо Корсика я использовал this
В моем тесте я искал 1000 шаблонов в двух документах, посвященных газетным бумагам, усредненным по 1000 итераций и т.д.... Нормализованное время для завершения:
AhoCorsick: 1
RabinKarp: 1,8
Наивный поиск (проверьте каждый шаблон и используйте string.contains): 50
* Некоторые ресурсы, описывающие альгоны, упомянутые в ответах ниже:
http://www.seas.gwu.edu/~simhaweb/cs151/lectures/module5/module5.html
http://www.cs.princeton.edu/courses/archive/spr09/cos226/lectures/18SubstringSearch-2x2.pdf