Доброго времени суток! Идея разбора данной задачи возникла на фоне обращения ко мне ученика на одном из ресурсов, где я выступаю в качестве frontend-ментора, с просьбой разобрать одну задачу. Суть задачи состояла в следующем:
Найти все доступные комбинаций предложений, полученных методом T9 (predictive text)
Вводные данные:
Файл combinations.txt, в котором описаны последовательности цифр, имитирующие пользовательский ввод:
Файл dictionary.txt, в котором представлен список английских слов, который используется для предсказания заданного слова из последовательности выше.
Выходные данные:
Файл output.txt, в котором собраны все возможные варианты предложений.
Разбор задачи
Первое, что приходит на ум, так это использовать префиксные деревья. А перед этим стоит пояснить что же это такое.
Префиксное дерево — структура данных для хранения строк, построенная в виде дерева, где на ребрах записаны символы, а некоторые вершины помечены как конечные. Классически данная структура может быть представлена изображением ниже:
Префиксное дерево проще всего хранить в виде ссылок на вершины. Каждая вершина обычно содержит информацию о том, является ли она конечной, ссылки на связаные вершины, а также любая дополнительная информация, зависящая от задачи.
Для латинского алфавита префиксное дерево может быть реализовано по приниципу ниже.
Перед тем как реализововывать дерево, в начале нам понадобится определить карту соответствия букв цифрам в раскладке клавиатуры кнопочного телефона:
Далее приступим к реализации непосредственно префиксного дерева. Для этих целей заведем класс Trie, который реализует два основных метода insert и getPredictions. Здесь вставка работает путем обхода дерева в соответствии со строкой, которая должна быть вставлена, а затем в суффикс строки добавляются новые узлы, не содержащиеся в дереве. Метод getPredictions работает путем прохода от корня по символам слова. Если в конце оказывается, что вершина конечна — то слово найдено, в противном случае нет.
Теперь реализуем класс для заполнения дерева и разбора словаря. Тут нет каких-то уникальных моментов, поэтому без комментариев.
Дело за малым — определиться, каким образом можно получить списки всех доступных комбинаций. Классический подход к генерации таких списков — алгоритм кучи, однако в нашем случае он не подходит, потому что мы хотим получить только уникальные варианты, а поэтому наиболее подходящий вариант — декартово произведение, реализация которого будет выглядеть следующим образом:
На этом самая сложная часть заканчивается, и осталось только вызвать реализованные методы. Код с комментариями находится ниже:
Код задачи доступен на моем гитхаб. Спасибо за внимание!
Сохраню статью и буду показывать её всем знакомым, которые будут говорить, что хотят "войти в айти". Это показательный пример склада ума, если можно так сказать, который должен быть, чтоб тебе было интересно в этой профессии.
Сохраню статью и буду показывать её всем знакомым, которые будут говорить, что хотят "войти в айти". Это показательный пример склада ума, если можно так сказать, который должен быть, чтоб тебе было интересно в этой профессии.