Если основное внимание уделяется производительности, я бы реализовал алгоритм, основанный на структуре trie
(хорошо работает, чтобы найти слова в тексте или помочь исправить слово, но в вашем случае вы можете быстро найти все слова, содержащие данное слово, или, например, все, кроме одной буквы).
Сначала перейдите по ссылке в Википедии выше .Tries
- это самый быстрый метод сортировки слов (n слов, поиск s, O (n) для создания trie, O (1) для поиска s (или, если вы предпочитаете, если a - средняя длина, O (an) для дерева и O (s) для поиска)).
Быстрая и простая реализация (для оптимизации) вашей проблемы (похожие слова) состоит из
- Составьте trie со списком слов, указав все буквы спереди и сзади (см. Пример ниже)
- Для поиска s выполните итерацию от s [0], чтобы найти слово в дереве, затем s [1] и т. Д.
- В дереве, если число найденных букв равно len (s) - k, отображается слово, где k - допуск (1 буква отсутствует, 2 ...).
- Алгоритм может быть расширен до слов в списке (см. Ниже)
Например, со словами car
, vars
.
Построение дерева (большая буква означает, что слово здесь заканчивается, а другая может продолжаться). >
- это постиндекс (переход вперед), а <
- предварительный индекс (переход назад). В другом примере нам, возможно, придется указать также начальную букву, она здесь не представлена для ясности.
Например, <
и >
в C ++ будут Mystruct *previous,*next
, то есть от a > c < r
, вы можете перейти непосредственно от a
к c
, и наоборот, также с a
на R
.
1. c < a < R
2. a > c < R
3. > v < r < S
4. R > a > c
5. > v < S
6. v < a < r < S
7. S > r > a > v
Если искать строго car, дерево дает вам доступ с 1., и вы найдете car (вы бы также нашли все, что начинается с car, но также что-нибудь с автомобилем внутри - этого нет в примере - но, например, vicar можно было бы найти в c > i > v < a < R
).
Чтобы выполнить поиск с допуском неправильной / отсутствующей 1 буквы, вы выполняете итерацию от каждой буквы s и подсчитываете количество последовательных - или пропуская 1 букву - букв, которые вы получаете от s < / em> в дереве.
ищу car
,
c
: поиск в дереве файлов c < a
и c < r
(пропущенная буква в s). Чтобы принять неправильную букву в слове w, попробуйте на каждой итерации перескакивать на неправильную букву, чтобы увидеть, не отстает ли ar
, это O (w). С двумя буквами, O (w ²) и т. Д., Но к дереву можно добавить еще один уровень индекса, чтобы учесть переход по буквам, в результате чего дерево сложный и жадный в отношении памяти.
a
, затем r
: то же, что и выше, но также поиск в обратном направлении
Это просто для того, чтобы дать представление о принципе - в приведенном выше примере могут быть некоторые сбои (завтра я еще раз проверю).
person
Community
schedule
26.08.2010
algorithm
. Вот несколько ссылок: - person j_random_hacker   schedule 01.09.2010