Почему мы используем Хэш-код в HashTable вместо Индекса?

В объекте 6.0 существует различие между:

context.Investments.Remove(entity);

и

context.Entry(entity).State = EntityState.Deleted;

Когда включено использование первого и каскадного удаления, EF внутренне выполнит необходимые удаления дочернего элемента. коллекции. При использовании второй опции EF не будет обрабатывать необходимые удаления, но позволит вам выполнить повторное связывание / удаление этих дочерних объектов.

6
задан lc. 23 May 2009 в 07:05
поделиться

4 ответа

По сути, хеш-функции используют некоторую общую функцию для переваривания данных и создания отпечатка пальца (и здесь целого числа) для этих данных. В отличие от индекса, этот отпечаток зависит ТОЛЬКО от данных и не должен иметь какой-либо предсказуемой упорядоченности на основе данных. Любое изменение одного бита данных также должно значительно изменить отпечаток пальца.

Обратите внимание, что это нигде не гарантирует, что разные данные не будут давать одинаковый хэш. На самом деле, как раз наоборот: это происходит очень часто и называется столкновением. Но с целым числом вероятность составляет примерно 1 из 4 миллиардов против этого (1 из 2 ^ 32). Если происходит коллизия, вы просто сравниваете реальный объект, который вы хэшируете, чтобы увидеть, совпадают ли они.

Затем этот отпечаток можно использовать в качестве индекса для массива (или arrayylist) сохраненных значений. Поскольку отпечаток пальца зависит только от данных, вы можете вычислить хэш для чего-то и просто проверить элемент массива на предмет этого хеш-значения, чтобы увидеть, было ли оно уже сохранено. В противном случае вам придется пройти через весь массив, проверяя, соответствует ли он элементу.

Вы также можете ОЧЕНЬ быстро создавать ассоциативные массивы, используя 2 массива: один со значениями ключей (индексируется хешем), а второй со значениями, сопоставленными с этими ключами. Если вы используете хеш, вам просто нужно знать хеш ключа, чтобы найти соответствующее значение для ключа. Это намного быстрее, чем выполнять двоичный поиск по отсортированному списку ключей или сканировать весь массив для поиска совпадающих ключей.

Существует МНОГО способов сгенерировать хэш, и все они имеют различные достоинства, но немногие из них просто. Я предлагаю обратиться к странице Википедии о хэш-функциях для получения дополнительной информации.

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

Вы также можете ОЧЕНЬ быстро создавать ассоциативные массивы, используя 2 массива: один со значениями ключей (индексируется хешем), а второй со значениями, сопоставленными с этими ключами. Если вы используете хеш, вам просто нужно знать хеш ключа, чтобы найти соответствующее значение для ключа. Это намного быстрее, чем выполнять двоичный поиск по отсортированному списку ключей или сканировать весь массив для поиска совпадающих ключей.

Существует МНОГО способов сгенерировать хэш, и все они имеют различные достоинства, но немногие из них просто. Я предлагаю обратиться к странице Википедии о хэш-функциях для получения дополнительной информации.

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

Вы также можете ОЧЕНЬ быстро создавать ассоциативные массивы, используя 2 массива: один со значениями ключей (индексируется хешем), а второй со значениями, сопоставленными с этими ключами. Если вы используете хеш, вам просто нужно знать хеш ключа, чтобы найти соответствующее значение для ключа. Это намного быстрее, чем выполнять двоичный поиск по отсортированному списку ключей или сканировать весь массив для поиска совпадающих ключей.

Существует МНОГО способов сгенерировать хэш, и все они имеют различные достоинства, но немногие из них просто. Я предлагаю обратиться к странице Википедии о хэш-функциях для получения дополнительной информации.

Вы также можете ОЧЕНЬ быстро создавать ассоциативные массивы, используя 2 массива: один со значениями ключей (индексируется хешем), а второй со значениями, сопоставленными с этими ключами. Если вы используете хеш, вам просто нужно знать хеш ключа, чтобы найти соответствующее значение для ключа. Это намного быстрее, чем выполнять двоичный поиск по отсортированному списку ключей или сканировать весь массив для поиска совпадающих ключей.

Существует МНОГО способов сгенерировать хэш, и все они имеют различные достоинства, но немногие из них просто. Я предлагаю обратиться к странице Википедии о хэш-функциях для получения дополнительной информации.

Вы также можете ОЧЕНЬ быстро создавать ассоциативные массивы, используя 2 массива: один со значениями ключей (индексируется хешем), а второй со значениями, сопоставленными с этими ключами. Если вы используете хеш, вам просто нужно знать хеш ключа, чтобы найти соответствующее значение для ключа. Это намного быстрее, чем выполнять двоичный поиск по отсортированному списку ключей или сканировать весь массив для поиска совпадающих ключей.

Существует МНОГО способов сгенерировать хэш, и все они имеют различные достоинства, но немногие из них просто. Я предлагаю обратиться к странице Википедии о хэш-функциях для получения дополнительной информации.

Это намного быстрее, чем выполнять двоичный поиск по отсортированному списку ключей или сканировать весь массив для поиска совпадающих ключей.

Существует МНОГО способов сгенерировать хэш, и все они имеют различные достоинства, но немногие из них просто. Я предлагаю обратиться к странице Википедии о хэш-функциях для получения дополнительной информации.

Это намного быстрее, чем выполнять двоичный поиск по отсортированному списку ключей или сканировать весь массив для поиска совпадающих ключей.

Существует МНОГО способов сгенерировать хэш, и все они имеют различные достоинства, но немногие из них просто. Я предлагаю обратиться к странице Википедии о хэш-функциях для получения дополнительной информации.

17
ответ дан 8 December 2019 в 05:23
поделиться

Хэш-код ЯВЛЯЕТСЯ индексом, а хеш-таблица на самом нижнем уровне ЯВЛЯЕТСЯ массивом. Но для данного значения ключа мы определяем индекс в хэш-таблице по-другому, чтобы ускорить поиск данных.

Пример: у вас есть 1000 слов и их определений. Вы хотите сохранить их, чтобы вы могли очень и очень быстро получить определение слова - быстрее, чем бинарный поиск, который вам пришлось бы делать с массивом.

Итак, вы создаете хеш-таблицу. Вы начинаете с массива, значительно превышающего 1000 записей - скажем, 5000 (чем больше, тем эффективнее по времени).

Вы используете свою таблицу так: вы берете слово, чтобы найти, и конвертируете ее в число от 0 до 4999. Вы выбираете алгоритм для этого; это алгоритм хеширования. Но вы, несомненно, могли бы написать что-то очень быстрое.

Затем вы используете преобразованное число в качестве индекса в свой массив из 5 000 элементов и вставляете / находите свое определение по этому индексу. Здесь вообще нет поиска: вы создали индекс непосредственно из поискового слова.

Все описанные мной операции выполняются с постоянным временем; ни один из них не займет больше времени, когда мы увеличим количество записей. Нам просто нужно убедиться, что в хэше достаточно места, чтобы свести к минимуму вероятность «коллизий», то есть вероятность того, что два разных слова будут преобразованы в один и тот же целочисленный индекс. Поскольку это может произойти с любым алгоритмом хеширования, нам нужно добавить проверки, чтобы увидеть, есть ли коллизия, и сделать что-то особенное (если «привет» и «мир» оба хешируют 1,234 и «привет» уже в таблице, что будем делать с "миром"? Проще всего поместить его в 1235 и настроить нашу логику поиска, чтобы учесть эту возможность.)

Изменить: после повторного прочтения вашего сообщения: алгоритм хеширования определенно не случайный, он должен быть детерминированным. Индекс, сгенерированный для "hello" в моем примере, должен быть 1 234 каждый раз; это единственный способ поиска.

5
ответ дан 8 December 2019 в 05:23
поделиться

HashCode - это псевдоуникальный ключ. Мы хотели бы иметь действительно уникальный ключ, но это невозможно. Мы соглашаемся на быструю и безопасную (без исключений) функцию.

HashTable использует HashCode для первоначального поиска за время O (1). Любая схема индексации требует времени O (log (n)). Но с неэффективной функцией HashCode обработка столкновений может значительно замедлить работу HashTable.

В .NET существует реализация по умолчанию для GetHashCode, но типы могут это переопределить.

System.String переопределяет GetHashCode (), потому что он переопределяет Equals (), а затем GetHashCode должен быть согласован.

1
ответ дан 8 December 2019 в 05:23
поделиться

Отвечая на каждый из ваших вопросов напрямую:

Как этот целочисленный хеш генерируется функция GetHashCode ()? Это случайное значение, которое не является уникальным?

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

В строке это переопределено, чтобы сделать уверен, что существует только один хеш код для конкретной строки. Как сделать это?

Есть много способов сделать это. Вот пример, который я тут же придумал:

int hash = 0;
for(int i = 0; i < theString.Length; ++i)
{
    hash ^= theString[i];
}

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

Как ускорить поиск определенного ключа в хэш-таблице с помощью хеш-кода? Каковы преимущества использования хэш-кода перед использованием индекса непосредственно в коллекции (например, в массивах)?

Хэш-код обычно используется в хеш-таблицах. Хеш-таблица - это массив, но каждая запись в массиве представляет собой «ведро» элементов, а не только один элемент. Если у вас есть объект и вы хотите знать, к какому сегменту он принадлежит, вычислите

 hash_value MOD hash_table_size. 

Затем вам просто нужно сравнить объект с каждым элементом в контейнере. Таким образом, поиск в хэш-таблице, скорее всего, будет иметь время поиска O (1), в отличие от O (log (N)) для отсортированного списка или O (N) для несортированного списка.

0
ответ дан 8 December 2019 в 05:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: