Tanımla: HashSet nedir?


420

HashSet C # HashSet veri yapısı .NET Framework 3.5'te kullanılmaya başlandı. Uygulanan üyelerin tam bir listesini HashSet MSDN sayfasında bulabilirsiniz.

  1. Nerede kullanılır?
  2. Neden kullanmak istersiniz?



Dahili bir hashtable kullanır. iyi bir karma uygulamanız varsa (örneğin, Sözlük <T>) HashSet'i kendiniz kolayca uygulayabilirsiniz.
Raz Megrelidze

Yanıtlar:


614
    1. A HashSet, bir nesne kümesini tutar, ancak bir nesnenin zaten kümede olup olmadığını kolayca ve hızlı bir şekilde belirlemenizi sağlar. Bunu bir diziyi dahili olarak yöneterek ve nesnenin hash kodundan hesaplanan bir dizin kullanarak depolayarak yapar. Buraya bir bak

    2. HashSetbenzersiz öğeler içeren sıralanmamış bir koleksiyon. Toplama, Kaldırma, İçerme gibi standart toplama işlemlerine sahiptir, ancak karma tabanlı bir uygulama kullandığından, bu işlemler O (1) 'dir. (Örneğin, İçerir ve Kaldır için O (n) olan List'in aksine. Birleşme , kavşak ve simetrik farkHashSet gibi standart küme işlemleri de sağlar . Buraya bir bak

  1. Setlerin farklı uygulamaları vardır. Bazıları, hash elemanları ile ekleme ve arama işlemlerini süper hızlı hale getirir. Ancak bu, öğelerin eklenme sırasının kaybolduğu anlamına gelir. Diğer uygulamalar, ek siparişi daha yavaş çalışma süreleri pahasına korur.

HashSetC # sınıfı böylece ilk yaklaşım için gider değil öğelerin sırasını koruyarak. Normalden çok daha hızlıdır List. Bazı temel ölçütler, HashSet'in birincil türlerle (int, double, bool vb.) İlgilenirken oldukça hızlı olduğunu gösterdi. Sınıf nesneleriyle çalışırken çok daha hızlıdır. Bu noktada HashSet hızlıdır.

Tek yakalama, HashSetendekslerin erişiminin olmamasıdır. Elemanlara erişmek için ya bir numaralandırıcı kullanabilir ya da HashSetiçine a dönüştürmek Listve bunu yinelemek için yerleşik işlevi kullanabilirsiniz . Buraya bir bak


13
Hashset ve benzeri iki şey, C # değil .NET'tir. Ayrıca HashSet siparişi korumaz. Bir karma kümesinden öğe eklemeyi ve kaldırmayı deneyin, daha sonra tekrarlayıp tekrarlayamayacağınızı
bileceksiniz

13

A HashSet, öğelerin hızlı bir şekilde aranabileceği ve tanımlanabileceği dahili bir yapıya (hash) sahiptir. Dezavantajı, bir HashSet(veya bir öğeyi dizine göre alma) yoluyla yinelemenin oldukça yavaş olmasıdır.

Öyleyse neden bir kümede bir girdinin var olup olmadığını neden bilmek istesin ki?

A'nın HashSetyararlı olduğu durumlardan biri , yinelemelerin olabileceği bir listeden farklı değerler elde etmektir. Bir öğe eklendikten sonra HashSet, öğenin var olup olmadığını belirlemek hızlıdır ( Containsoperatör).

Diğer avantajları HashSetKüme işlemleri şunlardır: IntersectWith, IsSubsetOf, IsSupersetOf, Overlaps, SymmetricExceptWith, UnionWith.

Nesne kısıtlama diline aşina iseniz, bu ayarlanmış işlemleri tanımlayacaksınız. Ayrıca, yürütülebilir UML uygulamasına bir adım daha yakın olduğunu göreceksiniz.


20
Re: olumsuz. Hayır, bir HashSet üzerinden yineleme yapmak oldukça hızlıdır. İkinci olarak, bir öğeyi dizine göre almak mümkün değildir. Aslında, elemanlar sıralanmamış olarak saklanır.
Nigel Touch

@Nigel Touch. Dizini (eklendikleri sıra) umursamıyorsanız tekrarlama hızlıdır. Ancak, dizinle ilgili endişeleriniz varsa, dizin her bir karma anahtarıyla birlikte saklanmalıdır ve bu nedenle yavaş olabilir, çünkü doğru öğeyi almak için liste ayrıntılı olarak aranmalıdır. Bu davranış, öğelerin eklendikleri sıraya göre dizine eklendiği listeden çok farklıdır.
k rey

Neden hızlı olacağı mantıklı, çünkü iki karma aynı değil. Sorgunun "kısa devre" yaklaşımından yararlanmasını sağlamak, belirli kriterleri hızla ortadan kaldırmak.
Chef_Code

8

Basitçe söylemek gerekirse ve mutfak sırlarını açığa vurmadan: genel olarak bir set, yinelenen öğeler içermeyen ve öğeleri belirli bir sırada olmayan bir koleksiyon. Bu nedenle, A HashSet<T>bir jenerik ile benzerdir List<T>, ancak sipariş kaybı pahasına hızlı aramalar için (adın ima ettiği gibi hashtables üzerinden) optimize edilmiştir.


1
Ancak bir HashSet <T>, her biri aynı içeriğe sahip aynı özelliklere sahip iki Ürün sınıfı gibi aynı verilere sahip iki nesne depolayabilir mi?
Johan Herstad

Sanırım asla bilemeyeceğiz
Denny

@JohanHerstad EqualityComparer'ın sınıfınız için bu özellikleri önemsediğini varsayarsak ya da HashSet'i bu özellikleri önemseyen bir IEqualityComparer ile inşa ederseniz, neden olmasın. HashSet için dokümantasyon bunun bir ya da tekliği belirlemek için diğer dayanmasıdır temizlemek yapar.
Bacon Bits

2

Uygulama perspektifinden bakıldığında, yalnızca yinelenenleri önlemek için ihtiyacınız HashSetvarsa, Arama, Ekle ve Kaldır karmaşıklıkları O (1) - sabit olduğundan aradığınız şey budur . Bunun anlamı, ne kadar elemanın HashSetolduğu önemli değildir, böyle bir eleman olup olmadığını kontrol etmek aynı zaman alacaktır, ayrıca O (1) 'de elemanlar eklediğiniz için bu tür şeyler için mükemmeldir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.