Saya sangat suka google golang tetapi dapatkah seseorang menjelaskan alasannya bagi para pelaksana karena tidak memiliki struktur data dasar seperti set dari pustaka standar?
Saya sangat suka google golang tetapi dapatkah seseorang menjelaskan alasannya bagi para pelaksana karena tidak memiliki struktur data dasar seperti set dari pustaka standar?
Jawaban:
Salah satu alasan potensial untuk penghilangan ini adalah sangat mudah untuk memodelkan set dengan peta.
Sejujurnya saya pikir itu agak terlalu kekeliruan, namun melihat Perl, ceritanya persis sama. Di Perl Anda mendapatkan daftar dan hashtable, di Go Anda mendapatkan array, irisan, dan peta. Di Perl, Anda biasanya menggunakan hashtable untuk setiap dan semua masalah yang berkaitan dengan set, hal yang sama berlaku untuk Go.
Contoh
untuk meniru set ints di Go, kami mendefinisikan peta:
set := make(map[int]bool)
Menambahkan sesuatu semudah:
i := valueToAdd()
set[i] = true
Menghapus sesuatu itu adil
delete(set, i)
Dan potensi kecanggungan dari konstruksi ini dengan mudah disarikan:
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
}
Dan hapus dan dapatkan dapat didefinisikan dengan cara yang sama, saya memiliki implementasi lengkap di sini . Ketidaksukaan utama di sini adalah fakta bahwa tidak memiliki obat generik. Namun dimungkinkan untuk melakukan ini dengan interface{}
dalam hal ini Anda akan mendapatkan hasil get.
map[int]bool
satu dapat menggunakan map[int]struct{}
sebagai gantinya. Saya lebih suka yang terakhir.
map[int]struct{}
.. struct{}
Dibutuhkan 0 byte.
map[int]struct{}
Anda tidak dapat melakukan if mymap["key"] {
untuk memeriksa keanggotaan. Google merekomendasikan penggunaanbool
(mencari "Satu set dapat diimplementasikan").
Saya pikir ini ada hubungannya dengan golang
fokus pada kesederhanaan. set
s menjadi benar-benar berguna dengan difference
, intersection
, union
, issubset
, dan sebagainya .. metode. Mungkin golang
tim merasa bahwa terlalu banyak untuk satu struktur data. Tetapi sebaliknya "set bodoh" yang hanya memiliki add
, contains
dan remove
dapat dengan mudah direplikasi dengan map
seperti yang dijelaskan oleh @jozefg.
Jawaban sebelumnya berfungsi HANYA JIKA kuncinya adalah tipe bawaan. Untuk melengkapi jawaban sebelumnya, berikut adalah cara untuk mengimplementasikan set yang elemen-elemennya adalah tipe yang ditentukan pengguna:
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))}
}
type mySet map[IntPoint]bool
bekerja dengan sangat baik. Semua yang diperlukan dari jenis kunci yang digunakan dalam peta adalah bahwa ia memiliki ==
dan!=
. Kesetaraan jenis struct didefinisikan dengan baik, Equals
metode Anda harus adil p1 == p2
.
Contains
butuh waktu linier, sementara aMap[]
butuh waktu konstan, berapapun jumlah anggotanya. Solusi yang lebih baik akan secara internal membuat kunci unik berdasarkan konten masing-masing anggota, dan memanfaatkan kueri waktu-konstan yang map
disediakan oleh tipe tersebut. Bahkan solusi yang lebih cepat yang mempertimbangkan perilaku cache, dll ada juga.