В приведенном вами примере производительность, скорее всего, не будет иметь значения, поскольку на ПК вся операция займет примерно 1% времени, которое требуется пользователю для чтения первого показанного вами результата, при условии, что вы не используете совершенно тупой алгоритм. Но, тем не менее, я предполагаю, что проблема достаточно велика, чтобы производительность была проблемой.
Если файл словаря предварительно отсортирован (как и большинство), и если текст невелик относительно словаря, который вы описываете, то у меня будет большой соблазн отсортировать текст, возможно, удалив дубликаты, и затем выполнить итерацию по обоим спискам бок о бок, используя ту же процедуру, что и сортировка слиянием, за исключением того, что вы сообщаете, есть ли каждое текстовое слово в словаре, вместо вывода объединенного списка.
Это выполняет работу, связанную с M log M сравнениями для сортировки, плюс не более N + M сравнений для итерации (возможно, меньше, но не сложнее). Это довольно близко к оптимальной сложности для одноразовой операции: чтобы избавиться от линейного члена в N, вам нужно найти способы вообще не читать весь словарь с диска. Я почти уверен, что можно выполнить поиск в файле, особенно если учесть, что слова довольно короткие, но для маленького N никто не знает, будет ли поиск места быстрее, чем последовательный доступ к данным.
Имеет следующие характеристики:
- Вам не нужно хранить словарь в памяти, только текст.
- Тем не менее, вы делаете только один проход по файлу словаря.
- Вы не занимаетесь дорогой обработкой словаря.
Конечно, если файл словаря предварительно не отсортирован, это не сработает, и если вы можете держать словарь в памяти для следующей операции проверки орфографии, то вы можете амортизировать стоимость ввода-вывода и обработка его в виде дерева по нескольким различным текстам, что в конечном итоге станет победой.
Если словарь действительно огромен, то вам может быть полезно хранить его на диске в предварительно обработанной форме, эквивалентной несбалансированному дереву, взвешенному в соответствии с относительными частотами различных слов в вашем языке. Тогда вы можете сделать меньше, чем O (N) доступ к диску для небольших текстов, и на большинстве ОС не загружать его вообще в память, просто mmap файл и позвольте ОС беспокоиться об этом. Для большого словаря не нужно трогать целые кластеры, содержащие слова, начинающиеся с «диметил».
Другое соображение - это дерево сплайнов для словаря. Splay-дерево разбалансирует себя, когда вы что-то ищите в нем, чтобы быстрее находить часто используемые значения. Большая часть текста использует небольшое количество слов несколько раз, поэтому, если текст достаточно длинный, чтобы оправдать накладные расходы, это в конечном итоге выиграет.
Оба вышеперечисленных предмета подчиняются пункту Стивена Лоу о том, что для строк три бьет нормальное дерево. Не знаю, найдёте ли вы готовый сплай-три.