@antoart
Web developer

Как сделать индекс по заданному тексту, и как по этому индексу потом искать?

Приветствую.
Прошу помочь в решении возникшей проблемы (задачи). Указать направление, помочь мудрым советом.

Есть задача:
-имеется список правильных названий программ ( а-ля шаблон, образец, эталон). Названия состоят из 1-6 слов
-имеется список названий программ, которые писали сотрудники. Сотрудники писали не по шаблону, допускали ошибки в написании самих слов, называли программы как-то иначе. При этом все равно сохранялась суть названия.
Например:
эталон "Программуля плюс"
сотрудник написал "Программа для документов Программуля"
Как видно, есть много лишнего, но суть сохранена.

Хочу создать индекс из справочника эталонных названий и как-то в этом индексе искать соответствия с пользовательским запросом ( либо есть совпадение, либо пользовательской программы в словаре нет).
Предполагаю, что ищем по отдельным словам исходные строки и ищем пересечения совпадений. Или не так?

Прошу подсказать как создается индекс, и как по этому индексу производится поиск (алгоритм).
Предметной базой сильно не владею, поэтому прошу объяснить простыми словами.
Писать буду на языке Java.

Спасибо за ответы :)

UPD:
Хочу поделиться с вами тем, как я сделал индекс.
Мне помогли ваши ответы и комментарии.

  1. взял строку. строка была вида original_Name : alternate_name_1, alternate_name_2
  2. запомнил оригинальное имя в отдельную переменную origName.
  3. очистил ее от мусора. Сюда входило удаление знаков пунктуации, там где у меня в строке были ссылки я сохранял тире "-". Убрал "стоп" слова. Стоп слова я выбрал посредством наблюдений в имеющемся словаре. Выбросил все слова, помимо предлогов и союзов, которые не носили смысловой нагрузки. У меня это были слова типа "портал", "online", общие аббревиатуры "ас", "абс".
  4. разбил строку на ключевые слова. Всю строку, включая и оригинальное название.
  5. сохранил в HashMap связку keyWord : origName. Где-то это называли метод обратных ссылок.
  6. если ключевые слова повторялись, то дописывал к origName другие слова в строку.


В получившемся "справочнике" я искал вхождения ключевых слов из запроса. На выходе получал список со всем найденными origName.
Ранжирование заключалось в том, что я считал наибольшее количество совпадений и считал эти совпадения результатом. Иногда было несколько совпадений с одинаковым количеством вхождений. Совпадения были похожими по смыслу, но вносили некую путаницу. (Эту проблему я решил диалоговым окном с "оператором" программы)

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

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

Хочу сказать спасибо тем, кто откликнулся на мои вопросы и дал комментарии.
Это
  • sirs @sirs
  • xmoonlight @xmoonlight
  • Walt Disney @ruFelix
  • Вопрос задан
  • 780 просмотров
Решения вопроса 1
@sirs
Тогда для быстрого старта я предлагаю вам использовать HashMap. В качестве ключей используете ключевые слова из названия программ, например:

Map<String, List<Software>> dictionary = new HashMap();
        List<Software> list = new ArrayList<Software>();
        programs.add(new Software("Программуля плюс"));
        programs.add(new Software("Программуля для детей"));
        programs.add(new Software("Автобусы. Программуля"));
        dictionary.put("Программуля", list);

и т.д.
Все ваши эталонные названия программ дробите на отдельные слова, объявляете каждое такое слово keywords. Тут нужно вводить ограничения на такие слова, например не менее 3 букв и только буквы и т.п. - тут вы должны сами определиться. Далее составляете списки программ, в которых встречаются такие ключевые слова, проверить если ли такая подстрока в строке - str1.toLowerCase().contains(str2.toLowerCase()).
Поиск в полученном словаре просто по ключу dictionary.get("Программуля "); - вернет вам список программ, в которых встречается искомая подстрока. Тут тоже перед тем как опрашивать - можно слегка оптимизировать, например привести к одному регистру, убрать пробелы в начале и конце и т.д.
Это самая простая реализация. Она не будет учитывать "похожие" слова, только совпадение подстроки в строке.
Сделайте все на интерфейсах, в процессе по линкам выше наберетесь знаний и сделаете более крутую реализацию, оставив интерфейс старым, подменив только реализацию.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@Roman_Kh
Вам нужен нечеткий поиск. Начальный экскурс в тему можно получить здесь и здесь.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы