Короткий ответ: Ваш поиск в первом дыхании на несколько порядков больше сравнивается на «единицу расстояния до слова» (далее - итерация).
- Вы сравниваете каждого кандидата с каждым оставшимся словом. Временная сложность T (N × n) за итерацию,
- Они сравнивают каждого кандидата с искусственно созданными «следующими» кандидатами. И поскольку они строят кандидатов, им не нужно «вычислять» расстояние. Для простоты я предполагаю, что оба (создание или проверка) имеют одинаковое время выполнения. Сложность по времени составляет T (26 × l × n) за итерацию.
(N = размер списка слов, n = количество кандидатов на эту итерацию, l = длина слова)
Конечно, 26 × l × n намного меньше, чем N × n, потому что длина слова мала, но список слов огромен.
Я попробовал вашу процедуру на ("and","has",[List of 2M English words])
и через 30 секунд я убил ее, потому что думал, что она разбилась. Это не разбилось, это было просто медленно. Я перешел к другому списку слов, состоящему из 50 КБ, и теперь у вас 8 секунд, вместо 0,04 с.
В моем списке слов N = 51306 есть 2167 трехбуквенных слов. Это означает, что на каждое слово в среднем приходится 3 × cbrt (2167) возможных кандидатов, что составляет n≈38,82.
- Их ожидаемая производительность: T (26 × l × n) ≈ T (3027) работа за итерацию,
- Ожидаемая производительность: T (N × n) ≈ T (1991784) работы на одну итерацию.
(при условии, что список слов не становится короче; но при таком количестве слов разница незначительна)
Кстати, ваша реализация циклического буфера на основе очереди, возможно, быстрее, чем их реализация с двумя чередующимися наборами, так что вы можете создать гибрид, который будет еще быстрее.