กำหนด: HashSet คืออะไร


420

HashSet โครงสร้างข้อมูล C # HashSet ถูกนำมาใช้ใน. NET Framework 3.5 รายการเต็มรูปแบบของสมาชิกในการดำเนินการที่สามารถพบได้ที่HashSet MSDNหน้า

  1. มันใช้อยู่ที่ไหน
  2. ทำไมคุณต้องการใช้


3
เป็นไปได้ที่ซ้ำกันของฉันควรใช้ประเภท HashSet <T> เมื่อใด
nawfal

มันใช้ hashtable ภายใน หากคุณมีการนำ hashtable ที่ดี (เช่น Dictionary <T>) คุณสามารถใช้ HashSet ได้อย่างง่ายดาย
Raz Megrelidze

คำตอบ:


614
    1. A HashSetเก็บชุดของวัตถุ แต่เป็นวิธีที่ช่วยให้คุณสามารถกำหนดได้อย่างง่ายดายและรวดเร็วว่าวัตถุนั้นอยู่ในชุดหรือไม่ มันทำได้โดยการจัดการภายในอาร์เรย์และจัดเก็บวัตถุโดยใช้ดัชนีซึ่งคำนวณจาก hashcode ของวัตถุ ลองดูที่นี่

    2. HashSetเป็นคอลเล็กชันที่ไม่เรียงลำดับที่มีองค์ประกอบเฉพาะ มีการดำเนินการรวบรวมมาตรฐานเพิ่มลบออกมี แต่เนื่องจากใช้การใช้งานแบบแฮชการดำเนินการเหล่านี้คือ O (1) (เมื่อเทียบกับรายการตัวอย่างซึ่งเป็น O (n) สำหรับการมีและลบ.) HashSetนอกจากนี้ยังมีการดำเนินงานกำหนดมาตรฐานเช่นสหภาพ , สี่แยกและแตกต่างสมมาตร ลองดูที่นี่

  1. มีการใช้งานที่แตกต่างกันของชุด บางคนทำการดำเนินการแทรกและค้นหาได้อย่างรวดเร็วด้วยองค์ประกอบการแปลงแป้นพิมพ์ อย่างไรก็ตามนั่นหมายความว่าลำดับที่เพิ่มองค์ประกอบนั้นหายไป การใช้งานอื่น ๆ รักษาคำสั่งเพิ่มเติมที่ค่าใช้จ่ายของเวลาทำงานช้าลง

HashSetชั้นใน C # จะไปสำหรับวิธีแรกจึงไม่รักษาคำสั่งขององค์ประกอบ มันเร็วกว่าปกติListมาก มาตรฐานพื้นฐานบางอย่างแสดงให้เห็นว่า HashSet เร็วขึ้นอย่างเหมาะสมเมื่อจัดการกับประเภทหลัก (int, double, bool, ฯลฯ ) มันเร็วขึ้นมากเมื่อทำงานกับคลาสอ็อบเจ็กต์ ดังนั้นประเด็นคือ HashSet นั้นรวดเร็ว

สิ่งที่จับได้เพียงอย่างเดียวHashSetคือไม่มีการเข้าถึงโดยดัชนี ในการเข้าถึงองค์ประกอบคุณสามารถใช้ตัวแจงนับหรือใช้ฟังก์ชันในตัวเพื่อแปลงค่าHashSetเป็น a Listและวนซ้ำไปเรื่อย ๆ ลองดูที่นี่


13
สองสิ่ง, hashset และคล้ายกันคือ. NET ไม่ใช่ C # HashSet ยังไม่รักษาลำดับ ลองเพิ่มและลบรายการออกจากชุดแฮชคุณจะรู้ว่าคุณวนซ้ำในภายหลัง ..
nawfal

13

A HashSetมีโครงสร้างภายใน (แฮช) ซึ่งสามารถค้นหาและระบุรายการได้อย่างรวดเร็ว ข้อเสียคือการวนซ้ำผ่านHashSet(หรือรับไอเท็มตามดัชนี) ค่อนข้างช้า

เหตุใดจึงมีคนต้องการทราบว่ารายการมีอยู่แล้วในชุด?

สถานการณ์หนึ่งที่มีHashSetประโยชน์คือการรับค่าที่แตกต่างจากรายการที่อาจมีซ้ำกัน เมื่อมีการเพิ่มรายการลงในรายการจะสามารถทราบHashSetได้อย่างรวดเร็วว่ามีรายการอยู่หรือContainsไม่

ประโยชน์อื่น ๆ ของการHashSetมีการดำเนินงานที่ตั้ง: IntersectWith, IsSubsetOf, IsSupersetOf, Overlaps, ,SymmetricExceptWithUnionWith

หากคุณคุ้นเคยกับภาษาข้อ จำกัด ของวัตถุคุณจะระบุการดำเนินการชุดเหล่านี้ คุณจะเห็นว่ามันเป็นขั้นตอนหนึ่งที่ใกล้เคียงกับการใช้ UML ที่ปฏิบัติการได้


20
Re: ข้อเสีย ไม่การทำซ้ำผ่าน HashSet นั้นรวดเร็วอย่างสมบูรณ์แบบ ประการที่สองมันเป็นไปไม่ได้ที่จะได้รับรายการโดยดัชนี ในความเป็นจริงองค์ประกอบจะถูกจัดเก็บแบบไม่มีการเรียงลำดับ
Nigel Touch

@ ไนเจลทัช การวนซ้ำเร็วถ้าคุณไม่สนใจเกี่ยวกับดัชนี (ลำดับที่เพิ่ม) อย่างไรก็ตามถ้าคุณมีความกังวลเกี่ยวกับดัชนีดัชนีนั้นจะต้องถูกเก็บไว้กับแต่ละคีย์แฮชและทำให้มันค่อนข้างช้าเพราะรายการจะต้องค้นหาอย่างละเอียดเพื่อดึงรายการที่ถูกต้อง พฤติกรรมนี้แตกต่างจากรายการที่จัดทำดัชนีรายการตามลำดับที่เพิ่มเข้ามา
k rey

มันสมเหตุสมผลแล้วทำไมมันถึงเร็วเพราะไม่มีแฮชสองอันเหมือนกัน การเปิดใช้งานแบบสอบถามเพื่อใช้ประโยชน์จากวิธี "ลัดวงจร" อย่างรวดเร็วพิจารณาเกณฑ์บางอย่าง
Chef_Code

8

พูดง่ายๆและไม่เปิดเผยความลับของครัว: ชุดโดยทั่วไปเป็นคอลเลกชันที่ไม่มีองค์ประกอบที่ซ้ำกันและองค์ประกอบที่ไม่มีลำดับใดเป็นพิเศษ ดังนั้น A HashSet<T>จึงคล้ายกับ generic List<T>แต่ได้รับการปรับให้เหมาะสำหรับการค้นหาที่รวดเร็ว (ผ่านแฮชเทเบิลตามที่ชื่อมีความหมาย) ในราคาที่เสียคำสั่ง


1
แต่ HashSet <T> สามารถเก็บวัตถุสองรายการที่มีข้อมูลเหมือนกันได้หรือไม่เช่นเดียวกับคลาสผลิตภัณฑ์สองรายการที่แต่ละรายการมีคุณสมบัติเดียวกันที่มีเนื้อหาเดียวกัน
Johan Herstad

ฉันเดาว่าเราจะไม่มีทางรู้หรอก
Denny

@JohanHerstad สมมติว่า EqualityComparer สำหรับชั้นเรียนของคุณสนใจคุณสมบัติเหล่านั้นหรือคุณสร้าง HashSet ด้วย IEqualityComparer ที่ใส่ใจเกี่ยวกับคุณสมบัติเหล่านั้นฉันไม่เห็นสาเหตุที่จะไม่เกิดขึ้น เอกสาร HashSetทำให้มันชัดเจนว่ามันขึ้นอยู่กับหนึ่งหรืออื่น ๆ เพื่อตรวจสอบเอกลักษณ์
เบคอน Bits

2

จากมุมมองของแอพลิเคชันหากความต้องการเพียงเพื่อที่จะหลีกเลี่ยงการซ้ำกันแล้วHashSetคือสิ่งที่คุณกำลังมองหาเพราะมันของการค้นหาแทรกและลบความซับซ้อนเป็น O (1) - คงที่ สิ่งนี้หมายความว่าไม่สำคัญว่าองค์ประกอบจำนวนมากHashSetจะใช้เวลาเท่ากันในการตรวจสอบว่ามีองค์ประกอบดังกล่าวหรือไม่รวมทั้งเนื่องจากคุณใส่องค์ประกอบที่ O (1) เช่นกันมันทำให้มันสมบูรณ์แบบสำหรับสิ่งนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.