2013-07-31 3 views
2

Я хотел бы создать метод, который ищет небольшую строку текста (обычно не более 256 символов) для существования любого из примерно 20 разных слов. Если он находит одно в тексте независимо от случая, он возвращает true.Эффективный текстовый поиск строк

Метод будет выполнен совсем немного (не сумасшедшая сумма), поэтому он должен быть как можно более эффективным. Что вы предлагаете лучше всего здесь?

20 слов не меняются. Они статичны. Но текст для сканирования делает.

+1

что вы пробовали ??? – ajduke

+0

И где находятся эти 20 слов? – fge

+0

Я не могу четко понять ваше требование, и вы хотите сказать, хотите ли вы искать, присутствует ли данное слово в String, которое содержит 20 слов? – Jayesh

ответ

5

Я бы предложил: добавить все слова во входной текст в Set - это всего лишь 256 символов, и их добавление - это операция O(n).

После этого вы можете проверить каждое из 20 слов для членства, используя операцию Set, которая составляет O(1).

2

В классе String уже есть много способов делать подобные вещи. Например, метод indexOf будет решить вашу проблему:

String str = "blahblahtestblah"; 
int result = str.indexOf("test"); 

result будет содержать -1, если строка не содержит слово «тест». Я не уверен, что это достаточно эффективно для вас, но я бы начал здесь, поскольку он уже реализован!

2

Предполагая, что эти 20 слов находятся в Set<String> и все в нижнем регистре, то это так же просто, как:

public final boolean containsWord(final String input) 
{ 
    final String s = input.toLowerCase(); 
    for (final String word: wordSet) 
     if (s.indexOf(word) != -1) 
      return true; 
    return false; 
} 
3

С 20 слов для поиска не меняются, один из самых быстрых способов поиска они компилируют регулярное выражение, которое соответствует им и повторно использует его на разных входах. Сложность сопоставления регулярного выражения с заданной строкой линейна по отношению к длине строки для простых регулярных выражений, которые не требуют обратного отслеживания. В вашем случае длина ограничена, поэтому это O (1).

+1

нет! это не будет O (1) ... 'indexof' или' hash' было бы лучше, чем использование regex, даже если регулярное выражение остается таким же. – Anirudha

+1

Ответы, которые предполагают, что набор предполагает, что входная строка состоит из дискретных слов. То, как я читаю OP, может быть или не быть. Возможно, ОП может уточнить? – andy256

+0

@ Анируд, поскольку все здесь имеет верхнюю границу (20 слов, 256 символов, ...), время выполнения любого достойного алгоритма также будет ограничено константой, поэтому O (1). Почему вы говорите, что 'indexOf' или хэш-таблица будет лучше, лучше в каком смысле? – Joni

0

Я хотел бы сделать следующее:

String longStr //the string to search into 
ArrayList<String> words; //the words to check 

Iterator<String> iter = words.iterator(); 
while(iter.hasNext()) 
{ 
    if(longStr.contains(iter.next())) 
     return true;  
} 
return false; 
+0

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

+0

while loop эффективен как цикл. – MaVVamaldo

+2

Но для этого требуется итератор, и ему очень больно читать. – Nicolas

0

Вы можете получить все слова в список, сортировать и использовать Collections.binarySearch (...). Вы потеряете при сортировке, но binarySearch - log (n).

1

Если вы хотите найти несколько разных целей одновременно, то возможно Rabin-Karp algorithm. Если это особенно эффективно, если в списке из 20 целей имеется только несколько разных длин слов. Один проход через строку найдет все совпадения заданной длины.

0

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

Я использовал структуру «Patricia Trie», которая представляет собой очень мощную и элегантную структуру данных, способную предлагать низкие накладные расходы памяти и чрезвычайно быструю скорость поиска.

Если кому-то интересно, есть video here, вкратце объясняющий, как работает Патрисия Три. Вы поймете, почему это так показательно после просмотра. Также существует реализация Java структуры данных на github here.