Создание хэша строки, которая сортируется - PullRequest
7 голосов
/ 05 января 2010

Есть ли способ создать хэши строк, в которых хэши могут быть отсортированы и дают такие же результаты, как если бы сами строки были отсортированы?

Ответы [ 6 ]

9 голосов
/ 05 января 2010

Это будет невозможно, по крайней мере, если вы разрешите строки длиннее размера хеша. У вас есть 256 ^ (макс. Размер строки) возможных строк, сопоставленных с 256 ^ (хеш-размером) хеш-значениями, так что некоторые строки не будут отсортированы.

Представьте себе самый простой хеш: усечение каждой строки до байтового размера.

6 голосов
/ 05 января 2010

Да. Он вызывается с использованием всей входной строки в качестве хэша.

2 голосов
/ 05 января 2010

Как уже отмечали другие, делать то, что вы просили, непрактично. Вы должны будете использовать саму строку в качестве хэша, которая будет ограничивать длину строк, которые могут быть «хешированы» и т. Д.

Очевидный подход к поддержанию структуры данных «отсортированный хэш» состоит в том, чтобы поддерживать как отсортированный список (например, кучу или двоичное дерево), так и хэшированное отображение данных. Вставки и удаления будут O (log (n)), а извлечения будут O (1). Я не уверен, как часто это будет стоить дополнительной сложности и накладных расходов.

Если у вас был особенно большой набор данных, в основном только для чтения и такой, что логарифмический поиск по времени был слишком дорогим, то я полагаю, что это может быть полезно. Обратите внимание, что стоимость обновлений фактически является суммой операций с постоянным временем (хэш) и логарифмическим временем (двоичное дерево или куча). Однако O (1) + O (log (n)) сводится к большему из двух членов во время асимптотического анализа. (Базовая стоимость все еще существует - относится к любым усилиям по внедрению независимо от их теоретической неактуальности).

Для значительного диапазона размеров наборов данных стоимость обслуживания этой гипотетической гибридной структуры данных может быть оценена как «двойная» стоимость обслуживания любого из чистых. (Другими словами, многие реализации двоичного дерева могут масштабироваться до миллиардов элементов (2 ^ ~ 32 или около того) во времени, сопоставимом со стоимостью типичных хеш-функций). Поэтому мне было бы трудно убедить себя, что такая дополнительная сложность кода и затраты времени выполнения (гибридной структуры данных) действительно будут полезны для данного проекта.

(Примечание: я видел, что в Python 3.1.1 добавлено понятие «упорядоченных» словарей ... и это похоже на сортировку, но не совсем так. Из того, что я собрал, упорядоченный словарь сохраняет порядок, в котором элементы были вставлены в коллекцию. Я также, кажется, помню некоторые разговоры о «представлениях» ... объектах в языке, которые могут обращаться к ключам словаря определенным образом (отсортировано, перевернуто, перевернуто, ...) при ( возможно) более низкая стоимость, чем передача набора ключей через встроенные "sorted ()" и "reversed ()". Я не использовал их и не смотрел на детали реализации. Я думаю, что один из них " Представления "были бы чем-то вроде лениво оцененного индекса, выполняющего необходимую сортировку по вызову и сохраняющего результаты с каким-либо флагом или триггером (шаблон наблюдателя или слушатель), который сбрасывается при обновлении коллекции исходного кода. В этой схеме вызов "view" обновит свой индекс, вызовы подпоследовательности смогут использовать эти результаты, если в словарь не было внесено ни вставок, ни удалений. Любой вызов представления после изменений ключа повлечет за собой затраты на обновление представления. Однако это все чисто домыслы с моей стороны. Я упоминаю об этом, потому что это может также дать представление о некоторых альтернативных способах решения вопроса).

1 голос
/ 05 января 2010

По сути, вы спрашиваете, можете ли вы сжать строки ключей в меньшие ключи, сохраняя их порядок сортировки. Так что это зависит от ваших данных. Например, если ваши строки состоят только из шестнадцатеричных цифр, их можно заменить на 4-битные коды.

Но в общем случае это невозможно сделать. В итоге вы «хэшируете» каждый ключ источника в себя.

1 голос
/ 05 января 2010

Нет. Хеш должен содержать то же количество информации, что и строка, которую он заменяет. В противном случае, если две строки сопоставлены одному и тому же хеш-значению, как вы можете их отсортировать?

Еще один способ думать об этом: если у меня есть две строки, «a» и «b», то я хеширую их обе с помощью этой хеш-функции, сохраняющей сортировку, и получаю f (a) и f (b). Тем не менее, существует бесконечное число строк, которые больше, чем «a», но меньше, чем «b». Это потребует хеширования строк с произвольной точностью. Реальные значения (из-за количества элементов). В конце концов, вам нужно просто закодировать строку как число.

1 голос
/ 05 января 2010

Нет, если строк меньше, чем хэшей, и хэши идеальны . Даже тогда вы все равно должны убедиться, что порядок хеширования совпадает с порядком строк, это, вероятно, невозможно, если вы не знаете все строки заранее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...