2013-03-03 2 views
9

У меня есть следующая ситуация: У меня есть большая коллекция строк (скажем, 250.000+) средней длины, возможно, 30. Что мне нужно сделайте много попыток в пределах этих .. в основном это будут StartsWith и Содержит вид.Какова самая быстрая структура или структура строк для запуска и/или содержит поисковые запросы

Коллекция является статической во время выполнения. Это означает, что первоначальное чтение и заполнение коллекции выбора выполняется только один раз. Поэтому выполнение построения структуры данных абсолютно не важно. Память также не является проблемой: это также означает, что я не против иметь две коллекции с одинаковыми данными в каждом случае, если это необходимо (например, один для startswith и другой для содержит). Единственное, что имеет значение, это выполнение поисков, которые должны возвращать все элементы, которые соответствуют условию поиска.

Для начала я столкнулся с деревом Trie или Radix .. но, возможно, есть еще лучшие варианты?

Для содержит. У меня пока нет хорошей идеи (помимо запуска запроса linq в списке, который не будет очень быстрым с этим объемом данных).

Заранее благодарен всем!

обновления: Я забыл важную роль: с Содержит я не имею в виду никаких точных совпадений в коллекции .. но я хочу, чтобы найти все строки в коллекции, которые содержат данное SearchString

+0

Будет ли подстрока для поиска Содержит поиск со словами или отдельными символами? Интересно, будет ли построение индекса иметь смысл для этого. –

+0

Он должен поддерживать персонажей. Несмотря на то, что по соображениям производительности я мог вообразить, чтобы перед поиском дать минимум 3 или более символов. (можно считать его автозаполнением в текстовом поле, которое начинается только после ввода некоторых символов) – Mikk

+1

Поиск в Интернете для «Rabin Karp». Это должно заставить вас начать, поскольку у него есть несколько алгоритмов поиска, связанных ... http: //www.stoimen.com/blog/2012/04/02/computer-algorithmms-rabin-karp-string-search/Также подумайте об использовании фильтра цветка и предварительно загрузите его своими строками при запуске. – JimR

ответ

3

, строящее suffix tree позволит вам выполните поиск подстроки по всем вашим строкам параллельно в O(1). Педантичный во мне не может не заметить, что это действительно O(n + m) где n - это количество строк, соответствующих вашей подстроке, и m - размер запрашиваемой подстроки.

Итак, что вы спрашиваете? В своей самой базовой реализации это trie с помощью метода вставки fancier: помимо добавления строки, он также добавляет все возможные суффиксы этой строки в trie. В этой структуре данных поиск подстрок становится префиксом поиска всех возможных суффиксов. Поскольку вы также хотите выполнять поиск в префиксах, вам нужно добавить специальный символ перед каждой вставленной строкой и подстроками запроса. Специальный символ позволит вам различать суффикс и полную строку.

Хотя эта реализация дерева суффикса замечательно проста, она также очень неэффективна (O(n^2) пространство и время сборки). К счастью, существуют и другие более эффективные реализации, которые могут значительно сократить пространство и временные рамки. Один из них, алгоритм Укконена, очень хорошо объяснен в this SO answer и сместил пространство до O(n). Вы также можете посмотреть в suffix arrays, которые являются эквивалентным, но более эффективным представлением суффиксов.

Хотя я знаю, что существует много других реализаций деревьев суффиксов (один из которых, вероятно, попадет в сладкое место для вашего случая использования), я просто не знаю их. Я рекомендую вам провести некоторое исследование по этому вопросу до того, как вы решитесь на реализацию.

+0

Вы ошибаетесь в отношении неэффективности дерева суффиксов. Хорошая реализация может улучшить время O (n) или O (n log n) и O (n). http://en.wikipedia.org/wiki/Suffix_tree – nhahtdh

+0

Звучит здорово! особенно идея со специальным символом для дифференциации суффикса и префиксов! – Mikk

+0

Я прочитаю об этом подробнее и попробую это точно. Будет ли недостаток в массивах суффиксов? Если они более эффективны, я, вероятно, сосредоточусь на них сразу. – Mikk