2009-05-14 4 views
7

Я немного поиграл с довольно простой, самодельной поисковой системой, и теперь я кручусь с некоторым кодом сортировки релевантности.Оптимизация простого алгоритма поиска

Это не очень красиво, но я не очень хорошо, когда дело доходит до умных алгоритмов, так что я надеялся, что я мог бы получить некоторые советы :)

В принципе, я хочу, чтобы каждый результат поиска, чтобы получить выигрыш на основе сколько слов соответствует критериям поиска. 3 балла за точным словом и одна точка для частичного совпадения

Например, если я ищу «зимний», это будут результаты:

  • зимойснег => 6 баллов
  • зимаснег ИНГ => 4 балла
  • зима земля снег => 4 балла
  • зима ВС => 3 балла
  • зима земля снег Ing => 2 балла

Вот код:

String[] resultWords = result.split(" "); 
String[] searchWords = searchStr.split(" "); 
int score = 0; 
for (String resultWord : resultWords) { 
    for (String searchWord : searchWords) { 
     if (resultWord.equalsIgnoreCase(searchWord)) 
      score += 3; 
     else if (resultWord.toLowerCase().contains(searchWord.toLowerCase())) 
      score++; 
    } 
} 
+1

В чем проблема, которую вы ищете? это слишком медленно? использует большие объемы памяти? какую оптимизацию вы имели в виду? – Yuval

+0

Speed ​​почти все. Оказывается, это может быть база данных, которая, однако, является «узким местом». – Ace

ответ

2

Ваш код кажется мне в порядке. Я предлагаю небольшие изменения:

Поскольку вы проходите все возможные комбинации, вы можете получить toLowerCase() своей спины в начале.

Кроме того, если точное совпадение уже произошло, вам не нужно выполнять другой equals.

result = result.toLowerCase(); 
    searchStr = searchStr.toLowerCase(); 

    String[] resultWords = result.split(" "); 
    String[] searchWords = searchStr.split(" "); 
    int score = 0; 
    for (String resultWord : resultWords) { 
     boolean exactMatch = false; 
     for (String searchWord : searchWords) { 
      if (!exactMatch && resultWord.equals(searchWord)) { 
       exactMatch = true; 
       score += 3; 
      } else if (resultWord.contains(searchWord)) 
       score++; 
     } 
    } 

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

+1

Я опоздал :(Единственное различие в том, что я назвал его точнымМатчиком. +1 –

+0

Полезная ссылка: http://moz.com/blog/search-engine-algorithm-basics – Justin808

0

Базовая оптимизация может быть выполнена путем предварительной обработки вашей базы данных: не разбивайте записи на слова каждый раз.

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

Выполняйте те же действия со строкой поиска при начале поиска (разделение, строчный регистр, очистка) и используйте этот список слов для сравнения с каждым списком слов ввода.

+0

Более продвинутая оптимизация может быть выполнена с помощью фильтрации форм слов (удаление общих окончаний), построение одного глобального хэша [word => db entry] и использование его для фильтрации ранних записей. Например, сравните только записи, имеющие хотя бы одно совпадение в глобальном хеше с одним из слов строки поиска. – Rageous

1
  • stemming
  • для акронимов важна чувствительность к регистру, то есть SUN; любое слово, которое соответствует как содержимому, так и случаю, должно быть взвешено более 3 баллов (5 или 7)?
  • использовать strategy design pattern

Для примера рассмотрим эту наивную оценка модели:

interface ScoreModel { 
    int startingScore(); 
    int partialMatch(); 
    int exactMatch(); 
} 

...

int search(String result, String searchStr, ScoreModel model) { 
    String[] resultWords = result.split(" "); 
    String[] searchWords = searchStr.split(" "); 
    int score = model.startingScore(); 

    for (String resultWord : resultWords) { 
     for (String searchWord : searchWords) { 
      if (resultWord.equalsIgnoreCase(searchWord)) { 
       score += model.exactMatch(); 
      } else if (resultWord.toLowerCase().contains(searchWord.toLowerCase())) { 
       score += model.partialMatch(); 
      } 
     } 
    } 

    return score; 
} 
0

1) Вы можете сортировать searchWords первым. Вы можете выйти из цикла после того, как ваше итоговое слово было в алфавитном порядке после вашего текущего слова поиска.

2) Еще лучше, сортируйте оба, затем пройдите по обоим спискам одновременно, чтобы найти, где происходят какие-либо совпадения.

0

Вы можете использовать регулярные выражения для поиска паттернов и длин совпадающих паттернов (для последней классификации/подсчета очков).

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