Если основное внимание уделяется производительности, я бы реализовал алгоритм, основанный на структуре trie
(хорошо подходит для поиска слов в тексте или для исправления слова, но в вашем случае вы можете быстро найти все слова, содержащие данное слово или, например, все буквы, кроме одной).
Пожалуйста, следуйте первымссылка на википедию выше. Tries
- самый быстрый способ сортировки слов ( n слов, поиск s , O ( n ) для создания дерева, O (1) для поиска s (или, если хотите, если a - средняя длина, O ( an ) для дерева и O ( s)) для поиска)).
Быстрая и простая реализация (для оптимизации) вашей задачи (аналогичные слова) состоит из
- Создайте три со списком слов, имеявсе буквы, проиндексированные спереди и сзади (см. пример ниже)
- Для поиска 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
Если строго присмотреться к машине , три дает вам доступ с 1., и вы найдете машину (вы также нашли бы все, начиная с car , но также и что-либо с автомобилем внутри - это не в примере - но викарий , например, был бы найден из c > i > v < a < R
).
Для поиска при разрешении 1-после неправильного / отсутствующего допуска, вы повторяете каждую букву s и подсчитываете количество последовательных - или, пропуская 1 букву - букв, которые вы получаете от s в дереве.
ищет car
,
c
: поиск по дереву для c < a
и c < r
(пропущена буква в s ).Чтобы принять неправильную букву в слове w , попробуйте на каждой итерации указывать неправильную букву, чтобы увидеть, находится ли ar
позади, это O ( w ).С двумя буквами, O ( w ²) и т. Д. ..., но можно добавить еще один уровень индекса в три, чтобы учесть скачок над буквами - делая сложное три,и жадный в отношении памяти. a
, затем r
: то же, что и выше, но поиск в обратном направлении также
Это просто для того, чтобы дать представление о принципе -В приведенном выше примере могут быть некоторые глюки (завтра проверю).