Go-利用Map实现类似Python的Set数据结构

该笔记参考《Go并发编程实战》

  • 首先实现一个自定义的HashSet

利用interface{}作为键,布尔型作为值。

package main

import (
"bytes"
"fmt"
) type HashSet struct {
m map[interface{}]bool
} func NewHashSet() {
return &HashSet{m: make(map[interface{}]bool)}
} func (set *HashSet) Add(e interface{}) bool {
if !set.m[e] {
set.m[e] = true
return true
}
return false
} func (set *HashSet) Remove(e interface{}) {
delete(set.m, e)
} func (set *HashSet) Clear() {
set.m = make(map[interface{}]bool)
} func (set *HashSet) Contains(e interface{}) bool {
return set.m[e]
} func (set *HashSet) Len() int {
return len(set.m)
} func (set *HashSet) Same(other Set) bool {
if other == nil {
return false
}
if set.Len() != other.Len() {
return false
}
for k := range set.m {
if !other.Contains(k) {
return false
}
}
return true
} func (set *HashSet) Elements() []interface{} {
initLen := len(set.m)
actualLen := 0
snapshot := make([]interface{}, initLen) for k := range set.m {
if actualLen < initLen {
snapshot[actualLen] = k
} else {
snapshot = append(snapshot, k)
}
actualLen++
}
if actualLen < initLen {
snapshot = snapshot[:actualLen]
}
return snapshot
} func (set *HashSet) String() string {
var buf bytes.Buffer
buf.WriteString("HastSet{")
first := true
for k := range set.m {
if first {
first = false
} else {
buf.WriteString(" ")
}
buf.WriteString(fmt.Sprintf("%v", k))
}
buf.WriteString("}")
}
  • 实现Set的基本特性
package main

type Set interface {
Add(e interface{}) bool
Remove(e interface{})
Clear()
Same(outher Set) bool
Elements() []interface{}
String() string
Len() int
Contains(e interface{}) bool
} func IsSuperSet(one Set, other Set) bool {
if one == nil || other == nil {
return false
}
oneLen := one.Len()
otherLen := other.Len()
if oneLen > 0 && otherLen == 0 {
return true
}
if oneLen == 0 && oneLen == otherLen {
return false
} for v := range other.Elements() {
if !one.Contains(v) {
return false
}
}
return true
} func Union(one Set, other Set) Set {
if one == nil || other == nil {
return false
}
unionedSet := NewSimpleSet()
for _, v := range one.Elements() {
unionedSet.Add(v)
}
if other.Len() == 0 {
return unionedSet
}
for v := range one.Elements() {
unionedSet.Add(v)
}
return unionedSet
} func Intersect(one Set, other Set) Set {
if one == nil || other == nil {
return false
}
intersectedSet := NewSimpleSet()
if other.Len() == 0 {
return intersectedSet
}
if one.Len() < other.Len() {
for _, v := range one.Elements() {
if other.Contains(v) {
intersectedSet.Add(v)
}
}
} else { for _, v := range other.Elements() {
if one.Contains(v) {
intersectedSet.Add(v)
}
}
}
return intersectedSet
} func NewSimpleSet() Set {
return NewHashSet()
}
func IsSet(value interface{}) bool {
if _, ok := value.(Set); ok {
return true
}
return false
}

至此,一个简单的Set集合就完成了。

上一篇:从零开始学习html(十)CSS格式化排版——下


下一篇:jstack实战死循环与死锁学习笔记