2012-03-27 2 views
5

У меня есть большой набор URL-адресов, и я хочу реализовать автозаполнение. Мне не нравится сложность наивный подход, как она линейна с заданным размером:Как создать простой префиксный индекс в Java?

for(String url: urls) if(url.startsWith(input) {doSomething();} 

Теперь я знаю, что в хэш-набор, функция «содержит()» работает в «O (1) «но нет« containsPrefix() ». Есть ли простой способ без использования большой библиотеки, такой как Lucene, или ее кодирования? У меня не было бы проблем с этим, но это кажется излишним для такой простой проблемы, поэтому я хочу знать, существует ли существующее простое решение :-)

Из моих классов компьютерных наук я помню дерево, состоящее из фрагментов строки, но Я забываю, как это называлось. Он работал следующим образом:

[car, care, carrot,carrotville]-> 

car 
| 
-/ 
-e 
-rrot 
    | 
    ----ville 

P.S .: Как я могу назвать методы, возвращающие все строки, для которых является префиксом строки? Например, если a является префиксом b, что такое b для a?

+0

Что вы хотите сделать? автоматически добавить текст в начале каждой строки? –

+0

Я хочу знать, какие строки моя строка является префиксом, поэтому я могу дать им варианты автозаполнения. –

ответ

2

Если вам нужно эффективно находить префиксы строк, используйте Trie, структуру данных, предназначенную именно для этой цели:

A синтаксического дерева, или префикс дерева, представляет собой упорядоченную структуру данных дерева, которое используется для хранить ассоциативный массив, где ключи обычно являются строками. В отличие от дерева двоичного поиска ни один узел в дереве не сохраняет ключ, связанный с этим узлом; вместо этого его позиция в дереве определяет ключ, с которым он связан. Все потомки узла имеют общий префикс строки, связанную с этим узлом, и корень связан с пустой строкой

Две связи с sampleimplementations.

+1

Отлично! Я использовал один из https://forums.oracle.com/forums/thread.jspa?messageID=8787521, и он работал с первой попытки! –

1

Долгое время назад я поставил простую реализацию TRIE здесь:

http://code.google.com/p/triebag/source/browse/trunk/src/triebag/tries/SimpleTrie.java

Однако это не компактный Trie, поэтому он создает один узел на символ, создавая компактный один немного сложнее.

+0

Это замечательно! Я не возражаю, если это один узел на каждого персонажа, но я оставлю вопрос открытым, если у кого-то есть один с кратным. –

+0

Np, compact version использует около% 50 узлов (по крайней мере, для турецких слов в словаре) Это тестовый код, поэтому вы можете увидеть его в действии, я надеюсь, что ошибок нет :) http: /code.google.com/p/triebag/source/browse/trunk/test/triebag/tries/SimpleTrieTest.java – mdakin

+0

Я опробовал ваш SimpleTrie, но он, похоже, не работает для меня. Сначала конструктор не был публичным, и после того, как я его изменил, следующий тест ничего не ответил: 'SimpleTrie trie = new SimpleTrie <>(); \t \t trie.add ("x", "x"); \t \t trie.add ("xy", "xy"); \t \t Итератор it = trie.getItemsWithPrefix ("x"); \t \t while (it.hasNext()) System.out.println (it.next()); ' –

0

Regexp java.util.regex.Pattern реализация может эффективно обрабатывать префиксы:

StringBuilder buffer = new StringBuilder(); 
for (String prefix : prefixes) { 
    if (buffer.length() > 0) 
     buffer.append("|"); 
    buffer.append(prefix); 
} 
Pattern prefixPattern = Pattern.compile("^(" + buffer + ")"); 

Вы можете проверить все префиксы:

boolean containsPrefix = prefixPattern.matcher(stringToTest).find(); 

Примечание: для простоты префиксные строки не экранированы. Регулярные символы [,], \, *,?, $, ^, (,), {,} И | должны иметь префикс \.

Смежные вопросы