2. Парсер текста
Цель
Реализовать парсер, который будет использоваться для нормализации поисковых запросов и содержимого документов. Покрыть тестами.
Инструменты
Для реализации рекомендуется использовать средства стандартной библиотеки C++:
Если вы реализуете алгоритм вручную, то это решение должно быть аргументированно.
При проверке работы учитываются:
Корректность алгоритма и качество тестов.
Идиоматичное использование C++.
Оптимальность (выбор структур данных, отсутствие избыточных аллокаций).
Алгоритм работы парсера
Вход:
Строка для разбора.
Параметры парсера:
Множество стоп-слов.
Минимальная и максимальная длина n-граммы.
Выход: разобранный запрос, состоящий из списка n-грам и позиций n-gram в тексте. Позиция определяется как индекс токена, не считая индексов стоп-слов.
Примерная последовательность преобразований входной строки:
Удалить знаки пунктуации. Для проверки можно использовать функцию std::ispunct.
Привести символы к нижнему регистру (std::tolower).
Разделить строку на слова по пробельным символам (std::isspace).
Удалить из получившегося списка слов стоп-слова.
Для каждого слова сгенерировать список n-грамм длиной от
min_ngram_lengthдоmax_ngram_length.
Стоп-слова — это слова, не влияющие на релевантность. Для первой итерации можете воспользоваться этим списком:
a
an
and
are
as
at
be
but
by
for
if
in
into
is
it
no
not
of
on
or
s
such
t
that
the
their
then
there
these
they
this
to
was
will
with
Пример
Вход:
text: "Dr. Jekyll and Mr. Hyde"
stop_words: ["and", "dr", "mr"]
ngram_min_length: 3
ngram_max_length: 6
Выход:
jek 0 jeky 0 jekyl 0 jekyll 0 hyd 1 hyde 1
Конфиг
Система поиска может содержать множество входных параметров. Передавать все через аргументы командной строки может быть слишком накладно, поэтому имеет смысл предусмотреть конфигурационный файл в машиночитаемом формате: xml, json или yaml. Для парсинга конфига вы можете использовать любую стороннюю библиотеку, например:
XML: pugixml
JSON: nlohmann::json, rapidjson
YAML: yaml-cpp
Возможный вариант xml-конфига:
<?xml version="1.0" encoding="utf-8"?>
<fts>
<parser ngram_min_length="3" ngram_max_length="6">
<stop_words>
<word>a</word>
<word>an</word>
…
</stop_words>
</parser>
</fts>
Путь к конфигурационному файлу удобно передавать через именованный аргумент командной строки, плюс предусмотреть ему значение по умолчанию:
--config <path> (default=config.xml)
Дополнительно
Для разных языков и наборов данных оптимальные параметры парсера могут отличаться. Уже на этом этапе имеет смысл предусмотреть формат конфигурационного файла для всей поисковой системы.