Отказ от ответственности: Я понимаю, что полностью очевидный ответ на этот вопрос HashSet
. Это нелепо быстро, это не заказано, и его значения уникальны.
Но я просто задаюсь вопросом, потому что HashSet
изменяемый класс, таким образом, он имеет Add
, Remove
, и т.д.; и таким образом, я не уверен, приносит ли базовая структура данных, которая делает эти операции возможными, определенные жертвы производительности когда дело доходит до операций чтения - в частности, я обеспокоен в Contains
.
В основном я задаюсь вопросом, что является абсолютными работающими самым быстрым образом существующими структурами данных, которые могут предоставить a Contains
метод для объектов типа string
. В или за пределами самой платформы.NET.
Я интересуюсь всеми видами ответов, независимо от их ограничений. Например, я могу предположить, что некоторая структура могла бы быть ограничена строками определенной длины или может быть оптимизирована в зависимости от проблемной области (например, диапазон возможных входных значений), и т.д. Если это существует, я хочу услышать об этом.
Одна последняя вещь: я не ограничиваю это структурами данных только для чтения. Очевидно, любая структура данных чтения-записи могла быть встроена в обертке только для чтения. Единственная причина я даже упомянул слово, "только для чтения", состоит в том, что у меня нет требования для структуры данных, чтобы позволить добавлять, удалять, и т.д. Если это будет иметь те функции, тем не менее, то я не буду жаловаться.
ОБНОВЛЕНИЕ:
Ответ идиота является превосходным примером вида вещи, которую я ищу. Trie* определенно походит на большую возможность по следующей причине: HashSet
зависит от GetHashCode
функция некоторых IEqualityComparer
, который, насколько я могу сказать, является O (n) ** по умолчанию в.NET. Другими словами, каждый символ в строке должен быть исследован на HashSet
возвратиться также true
или false
. Для a Trie
, только возвращаемое значение true
взял бы O (n) для определения; возвращаемое значение false
мог потенциально возвратиться намного более быстро.
Это, конечно, гипотетически. До сих пор я не записал или столкнулся с реализацией Trie в.NET, которая может разбить a HashSet
в Contains
(хотя реализация, которую я записал сам, вполне приблизилась для алфавита к 'z'). Я просто говорю, это кажется возможным.
*Что ссылка, между прочим, также привела меня к другой интригующей/подобной возможности: DAWG.
** Здесь "n" относится к длине строки.
Помимо вашего удивительного Hashset - это самая быстрая коллекция.
Нет более быстрого метода, потому что лежащая в основе Hashtable разрешает O (1) чтение-запись-доступ
Попытки хороши для выполнения Содержит
, особенно для строк из конечного алфавита. Для строки s временная сложность для Contains в дереве равна O (| s |) (| s | = длина s), что является оптимальным.
Контейнер хеширования приближается к O (1) для вставки и извлечения, так что с точки зрения порядка вы не можете найти ничего лучше этого.
В хеш-контейнере ваша производительность с течением времени будет зависеть от двух вещей: насколько хорошее распределение обеспечивает ваша хеш-функция и насколько быстро она может его вычислить. Они не эквивалентны - плохо распределенная функция (где вы в конечном итоге получаете много коллизий) будет гораздо более влиять на производительность, чем более медленная, но лучше распределенная хеш-функция.
Таким образом, если бы вы могли придумать идеальную хеш-функцию, которая также была бы чрезвычайно быстрой для вычисления, это было бы улучшением. Возможно, это упростит ограничение данных определенными способами. Но, скорее всего, все, что вы придумаете, будет не так хорошо, как то, что уже существует.
Таблицы хеширования амортизируются O (1) для поиска. Нет ничего лучше, чем это, алгоритмы O (1 / n) - это устройства с вечным двигателем. Есть только две вещи, которые заставляют их вести себя плохо:
Подобные проблемы возникают редко. Вы не разрабатываете для них заранее (кроме хэш-функции), вы начинаете рассматривать их только тогда, когда обнаруживаете проблемы с производительностью в программе.