Визначте: що таке HashSet?


420

HashSet Структура даних C # HashSet була представлена ​​в .NET Framework 3.5. Повний список реалізованих членів можна знайти на сторінці HashSet MSDN .

  1. Де він використовується?
  2. Чому б ви хотіли ним користуватися?



Він використовує хешбел всередині. якщо у вас є хороша реалізація хештелю (наприклад, словник <T>), ви можете легко реалізувати HashSet.
Raz Megrelidze

Відповіді:


614
    1. A HashSetмістить набір об'єктів, але таким чином, що дозволяє легко і швидко визначити, об’єкт вже в наборі чи ні. Це робиться за допомогою внутрішнього управління масивом і зберігання об'єкта за допомогою індексу, який обчислюється з хеш-коду об'єкта. Погляньте тут

    2. HashSetце не упорядкована колекція, що містить унікальні елементи. У ньому є стандартні операції збору «Додати, видалити», «містить», але оскільки він використовує хеш-реалізацію, ці операції є O (1). (На відміну, наприклад, від List, який є O (n) для Contains and Remove.) HashSetТакож забезпечує операції стандартного набору, такі як об'єднання , перетин та симетрична різниця . Погляньте тут

  1. Існують різні реалізації наборів. Деякі роблять операції з вставки та пошуку дуже швидкими хеш-елементами. Однак це означає, що порядок додавання елементів втрачається. Інші реалізації зберігають доданий порядок за рахунок більш повільного часу роботи.

HashSetКлас в C # йде на перший підхід, таким чином , НЕ зберігаючи порядок елементів. Це набагато швидше, ніж звичайний List. Деякі основні орієнтири показали, що HashSet є пристойно швидшим при роботі з первинними типами (int, double, bool тощо). Це набагато швидше при роботі з об’єктами класу. Отже, це в тому, що HashSet швидкий.

Єдине відгадка HashSet- це відсутність доступу за показниками. Для доступу до елементів ви можете або використовувати перечислювач, або використовувати вбудовану функцію для перетворення HashSetв а Listта повторення через це. Погляньте тут


13
Дві речі, хешсет і подібне - це .NET, а не C #. Також HashSet не зберігає порядок. Спробуйте додати та видалити елементи з хеш-набору, ви дізнаєтесь, чи повторите пізніше ..
nawfal

13

А HashSetмає внутрішню структуру (хеш), за якою елементи можна швидко шукати та ідентифікувати. Мінус полягає в тому, що повторення HashSet(або отримання елемента за індексом) відбувається досить повільно.

То чому б хтось хотів мати можливість знати, якщо запис у наборі вже існує?

Одна з ситуацій, коли a HashSetкорисна, - це отримання чітких значень зі списку, де можуть бути дублікати. Після додавання елемента до HashSetнього можна швидко визначити, чи існує елемент ( Containsоператор).

Інші переваги HashSetє операції Set: IntersectWith, IsSubsetOf, IsSupersetOf, Overlaps, SymmetricExceptWith, UnionWith.

Якщо ви знайомі з мовою обмеження об'єкта, ви визначите ці задані операції. Ви також побачите, що це на крок ближче до реалізації виконуваного UML.


20
Re: зворотний бік. Ні, ітерація через HashSet ідеально швидка. По-друге, неможливо отримати елемент за індексом. Насправді елементи зберігаються без упорядкування.
Nigel Touch

@Nigel Touch. Ітерація проходить швидко, якщо вам не байдуже індекс (порядок їх додавання). Однак, якщо ви стурбовані індексом, то індекс повинен зберігатися з кожним хеш-ключем, і тому він може бути досить повільним, оскільки в списку потрібно вичерпно шукати список, щоб отримати правильний елемент. Така поведінка сильно відрізняється від списку, в якому елементи індексуються порядком, в якому вони додані.
k rey

Це має сенс, чому це було б швидко, бо жоден два хешу не є однаковими. Дозволяючи запиту скористатися підходом "короткого замикання", швидко виключаючи певні критерії.
Chef_Code

8

Простіше сказати і не розкриваючи кухонних секретів: набір в цілому - це колекція, яка не містить дублюючих елементів і елементи яких не впорядковані. Отже, A HashSet<T>схожий на загальний List<T>, але оптимізований для швидкого пошуку (за допомогою хештелів, як випливає з назви) ціною втрати порядку.


1
Але чи може HashSet <T> зберігати два об'єкти, що мають однакові дані, як два класи продукту, кожен з яких має однакові властивості з однаковим вмістом?
Йохан Герстад

Напевно, ми ніколи не дізнаємось
Денні

@JohanHerstad Припускаючи, що рівністьComparer для вашого класу піклується про ці властивості, або ви конструюєте HashSet з IEqualityComparer, який піклується про ці властивості, я не розумію, чому це не було б. У документації на HashSet чітко видно, що для визначення унікальності вона покладається на те чи інше.
Шматочки бекону

2

З точки зору програми, якщо вам потрібно лише уникати дублікатів, то HashSetце те, що ви шукаєте, оскільки складності пошуку, вставки та видалення є O (1) - постійними . Це означає, що не має значення, скільки елементів у HashSetвас буде потрібно стільки ж часу, щоб перевірити, чи є такий елемент чи ні, плюс оскільки ви вставляєте елементи в O (1), це також робить його ідеальним для подібних речей.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.