亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我想知道如何將 set struct 實現為映射值

我想知道如何將 set struct 實現為映射值

Go
智慧大石 2023-05-08 16:13:12
我想在 golang 上使用 set 作為映射值。所以我這樣編碼:import (   "fmt"   "reflect")type TestSet struct {   Items []Test}func (ts *TestSet) Add(t *Test) {   ok := true   for _, item := range ts.Items {      if item.Equal(t) {         ok = false         break      }   }   if ok {      ts.Items = append(ts.Items, *t)   }}type Test struct {   phoneNumber string   name        string   friends     []string // i add this field! (**edit**)}func (t *Test) Equal(t2 *Test) bool {   if t.phoneNumber != t2.phoneNumber || t.name != t2.name {      return false   }   if !reflect.DeepEqual(t.friends, t2.friends) {      return false   }   return true}我想使用如下代碼的結構:val := make(map[int]*TestSet)val[1] = &TestSet{}val[1].Add(&Test{phoneNumber: "8210", name: "minji", friends: []string{"myself"})然而,我TestSet總是必須遍歷整個項目才能存在它的價值。所以Add()時間復雜度O(n)。我想將時間復雜度降低到 O(1)。(像蟒蛇集 in)但是,我不知道該怎么辦。我應該使用另一張地圖嗎?有什么好主意嗎?
查看完整描述

3 回答

?
慕森王

TA貢獻1777條經驗 獲得超3個贊

集合通常作為沒有值的映射來實現。Astruct{}在 Go 中實際上是空的。


type Empty struct {}


type TestSet struct {

? ?set map[Test]Empty

}

為了使其起作用,Test必須具有可比性。

如果結構值的所有字段都具有可比性,則結構值是可比的。如果兩個結構值對應的非空白字段相等,則它們相等。


所以Test具有可比性。

package main;


import (

? ? "fmt"

)


type Empty struct {}


type TestSet struct {

? ? set map[Test]Empty

}


func (ts *TestSet) Add(t Test) bool {

? ? if _, present := ts.set[t]; present {

? ? ? ? return false

? ? } else {

? ? ? ? ts.set[t] = Empty{}

? ? ? ? return true

? ? }

}


type Test struct {

? ? phoneNumber string

? ? name? ? ? ? string

}


func main() {

? ? set := TestSet{ set: make(map[Test]Empty) }

? ? test1 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }

? ? test2 := Test{ phoneNumber: "555-555-5555", name: "Yarrow Hock" }

? ? test3 := Test{ phoneNumber: "123-555-5555", name: "Yarrow Hock" }

? ? if set.Add( test1 ) {

? ? ? ? fmt.Println("Added 1")

? ? }

? ? if set.Add( test2 ) {

? ? ? ? fmt.Println("Added 2")

? ? }

? ? if set.Add( test3 ) {

? ? ? ? fmt.Println("Added 3")

? ? }


? ? for test := range set.set {

? ? ? ? fmt.Println(test.phoneNumber)

? ? }

}

您還可以使用golang-set 庫。



查看完整回答
反對 回復 2023-05-08
?
白豬掌柜的

TA貢獻1893條經驗 獲得超10個贊

也許,像這樣:


package main


type Test struct {

    phoneNumber string

    name        string

}


type TestSet struct {

    Items map[string]bool

}


func (ts *TestSet) Add(t *Test) {

    ts.Items[t.phoneNumber+"\x80"+t.name] = true

}


func main() {}

游樂場:https://play.golang.org/p/48fVQcvp3sW


查看完整回答
反對 回復 2023-05-08
?
揚帆大魚

TA貢獻1799條經驗 獲得超9個贊

您可以通過將值類型設為 map 來模擬 golang 中的集合struct{}。您的結構的一些示例代碼Test:


package main


import "fmt"


type TestSet map[Test]struct{}


func (ts TestSet) Add(t Test) {

? ? ts[t] = struct{}{}

}


type Test struct {

? ? phoneNumber string

? ? name string

}


func main() {

? ? ts := TestSet{}

? ? t1 := Test{"a", "b"}

? ? t2 := Test{"a", "b"}

? ? ts.Add(t1)

? ? ts.Add(t2)


? ? fmt.Println(ts) // Output: map[{a b}:{}]

}

這與您的函數簽名不完全匹配,因為我使用值而不是引用。這意味著我不必Equals像您那樣定義自定義函數。此外,通過將參數作為值傳遞,映射檢查結構本身的相等性而不是引用。


需要注意的是,此方法僅在結構具有可比性時才有效。


查看完整回答
反對 回復 2023-05-08
  • 3 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號