กำหนดโครงสร้างข้อมูลใน Golang


69

ฉันชอบ google golang แต่บางคนสามารถอธิบายได้ว่าเหตุผลสำหรับผู้ใช้งานที่มีโครงสร้างข้อมูลพื้นฐานเช่นชุดจากไลบรารีมาตรฐานคืออะไร


8
ภาษานี้มีชื่อเรียกว่า Go ไม่ใช่ golang
jozefg

92
แต่ "golang" สามารถค้นหาได้มากขึ้น
แมตต์

18
ค้นหาได้ง่ายขึ้น Googling "go set" ส่งคืนรูปภาพของกระดานไม้ที่มีชิ้นส่วนขาวดำ
Doug Richardson

คำตอบ:


68

เหตุผลหนึ่งที่เป็นไปได้สำหรับการละเลยนี้คือมันง่ายมากที่จะตั้งค่าโมเดลด้วยแผนที่

พูดตามตรงฉันคิดว่ามันเป็นเรื่องของการกำกับดูแลเหมือนกันอย่างไรก็ตามการดู Perl เรื่องราวก็เหมือนกันทุกประการ ใน Perl คุณจะได้รับรายชื่อและแฮชเทเบิลใน Go คุณจะได้รับอาร์เรย์ชิ้นและแผนที่ ใน Perl คุณมักใช้ hashtable สำหรับปัญหาใด ๆ และทั้งหมดที่เกี่ยวข้องกับเซต

ตัวอย่าง

เพื่อเลียนแบบชุด int ใน Go เรากำหนดแผนที่:

set := make(map[int]bool)

ในการเพิ่มบางอย่างนั้นง่ายเหมือน:

i := valueToAdd()
set[i] = true

การลบบางสิ่งเป็นเพียง

delete(set, i)

และศักยภาพที่น่าอึดอัดใจของสิ่งก่อสร้างนี้ก็ถูกแยกออกไปอย่างง่ายดาย:

type IntSet struct {
    set map[int]bool
}

func (set *IntSet) Add(i int) bool {
    _, found := set.set[i]
    set.set[i] = true
    return !found   //False if it existed already
}

และลบและได้รับการสามารถกำหนดได้ในทำนองเดียวกันผมมีการดำเนินงานที่สมบูรณ์แบบที่นี่ ความไม่ลงรอยกันที่สำคัญที่นี่คือความจริงที่ว่ามันไม่มียาชื่อสามัญ อย่างไรก็ตามมันเป็นไปได้ที่จะทำเช่นนี้interface{}ในกรณีที่คุณได้รับผลการค้นหา


3
นี่คือรุ่นที่แก้ไขเล็กน้อยของฉันด้วยวิธีการบรรจุและขนาด: play.golang.org/p/tDdutH672-
Rick-777

19
แทนmap[int]boolหนึ่งสามารถใช้map[int]struct{}แทน ฉันชอบที่สุด
pepper_chico

20
map[int]struct{}.. struct{}ใช้เวลา 0 ไบต์
Boopathi Rajaa

2
github.com/fatih/setเป็นการใช้งานแผนที่และโครงสร้างที่ว่างเปล่าของฉัน มันด้ายปลอดภัยและมี API ง่าย
Fatih Arslan

6
ด้วยmap[int]struct{}คุณไม่สามารถทำif mymap["key"] {เพื่อตรวจสอบการเป็นสมาชิก Google แนะนำให้ใช้bool (ค้นหา "ชุดสามารถนำไปใช้งานได้")
Timmmm

3

ฉันคิดว่าสิ่งนี้เกี่ยวข้องกับgolangความเรียบง่าย sets เป็นประโยชน์จริงๆกับdifference, intersection, union, issubsetและอื่น ๆ .. วิธีการ บางทีgolangทีมอาจรู้สึกว่ามันมีโครงสร้างข้อมูลมากเกินไป แต่อย่างอื่น "ชุดโง่" ที่มีเพียงadd, containsและremoveสามารถทำซ้ำได้อย่างง่ายดายด้วยmapตามที่อธิบายไว้โดย @jozefg


ฉันไม่เห็นด้วย. ชุดส่วนใหญ่จะใช้สำหรับการตรวจสอบการเป็นสมาชิกและความหมายที่ไม่สม่ำเสมอ ชุดการใช้งานจะสามารถใช้งานได้อย่างสมบูรณ์แบบโดยไม่มีวิธีการเหล่านั้น ที่ถูกกล่าวว่าพวกเขายังนำไปปฏิบัติเล็กน้อย
Sedat Kapanoglu

2

คำตอบก่อนหน้านี้ทำงานได้เฉพาะในกรณีที่คีย์เป็นชนิดในตัว เพื่อเติมเต็มคำตอบก่อนหน้านี้ต่อไปนี้เป็นวิธีการใช้ชุดที่องค์ประกอบเป็นชนิดที่ผู้ใช้กำหนด:

package math

// types

type IntPoint struct {
    X, Y int
}

// set implementation for small number of items
type IntPointSet struct {
    slice []IntPoint 
}

// functions

func (p1 IntPoint) Equals(p2 IntPoint) bool {
    return (p1.X == p2.X) && (p1.Y == p2.Y)
}

func (set *IntPointSet) Add(p IntPoint) {
    if ! set.Contains(p) {
        set.slice = append(set.slice, p)
    }
}

func (set IntPointSet) Contains(p IntPoint) bool {
  for _, v := range set.slice {
    if v.Equals(p) {
      return true
    }
  }
  return false
}

func (set IntPointSet) NumElements() int {
    return len(set.slice)
}

func NewIntPointSet() IntPointSet {
  return IntPointSet{(make([]IntPoint, 0, 10))}
}

8
"ทำงานเฉพาะกรณีที่สำคัญที่มีในตัวพิมพ์" เป็นที่ไม่ถูกต้อง type mySet map[IntPoint]boolทำงานได้อย่างสมบูรณ์แบบดี ทั้งหมดที่จำเป็นชนิดที่สำคัญที่ใช้ในแผนที่คือว่ามันมี==!=และ ความเท่าเทียมกันของชนิด struct ถูกกำหนดไว้อย่างดีของคุณวิธีการที่ควรจะเป็นเพียงแค่Equals p1 == p2
เดฟ C

1
มันเป็นความจริงที่ความเท่าเทียมกันสำหรับ structs นั้นถูกกำหนดไว้อย่างดี แต่ถ้า struct มีการแมปหรือส่วนข้อมูลเป็นฟิลด์พวกมันจะถูกเปรียบเทียบโดยการอ้างอิงแทนที่จะเป็นตามค่า นี่อาจไม่ใช่สิ่งที่คุณต้องการ
Chaim-Leib Halbert

1
ฉันใช้เวลาเล็กน้อยในการแก้ปัญหานี้เพราะContainsใช้เวลาเชิงเส้นในขณะที่aMap[]ใช้เวลาคงที่โดยไม่คำนึงถึงจำนวนสมาชิก ทางออกที่ดีกว่าจะสร้างคีย์ที่ไม่ซ้ำกันภายในขึ้นอยู่กับเนื้อหาของสมาชิกแต่ละคนและใช้ประโยชน์จากการสอบถามเวลาคงที่ที่mapประเภทให้ แม้แต่โซลูชันที่เร็วขึ้นซึ่งพิจารณาพฤติกรรมแคช ฯลฯ ก็มีอยู่เช่นกัน
Chaim-Leib Halbert
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.