go之实现集合及操作

qii · · 2255 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

package set

import (
   "fmt"
   "bytes"
)

type HashSet struct{
   m map[interface{}]bool
}

func NewHashSet() *HashSet{
   return &HashSet{m:make(map[interface{}]bool)}
}

func (self *HashSet) Add(e interface{}) bool{
   if self.m[e]{
      return false
   }
   self.m[e] = true
   return true
}

func (self *HashSet) Remove(e interface{}) bool{
   delete(self.m, e)
   return true
}

func (self *HashSet) Clear() bool  {
   self.m = make(map[interface{}]bool)
   return true
}

func (self *HashSet) Contains(e interface{}) bool {
   return self.m[e]
}

func (self *HashSet) Len() int {
   return len(self.m)
}

func (self *HashSet) Same(other *HashSet) bool{
   if other == nil {
      return false
   }

   if self.Len() != other.Len(){
      return false
   }

   for k,_ := range other.m{
      if !self.Contains(k){
         return false
      }
   }
   return true
}

func (self *HashSet) Elements() interface{} {
   // for k := range self.m{
   //    snapshot = snapshot(snapshot, k)
   // }
   initialLen := self.Len()
   actualLen := 0
   snapshot := make([]interface{}, initialLen)
   for k := range self.m{
      if actualLen < initialLen{
         snapshot[actualLen] = k
      } else {
         snapshot = append(snapshot, k)
      }
      actualLen ++
   }
   if actualLen < initialLen{
      snapshot = snapshot[:actualLen]
   }
   return snapshot
}

func (self *HashSet) String() string {
   var buf bytes.Buffer
   buf.WriteString("Set{")
   flag := true
   for k := range self.m{
      if flag {
         flag = false
      } else {
         buf.WriteString(" ")
      }
      buf.WriteString(fmt.Sprintf("%v", k))
   }
   buf.WriteString("}")

   return buf.String()
}

func (self *HashSet) IsSuperSet(other *HashSet) bool {
   if other == nil{
      return false
   }
   selfLen := self.Len()
   otherLen := other.Len()
   if otherLen == 0 || selfLen == otherLen {
      return false
   }
   if selfLen > 0 && otherLen == 0{
      return true
   }
   for v := range other.m{
      if !self.Contains(v){
         return false
      }
   }
   return true
}

//属于A或属于B的元素
func (self *HashSet) Union(other *HashSet) *HashSet {
   // if other == nil || other.Len() == 0{
   //    return self
   // }
   //
   // for v := range other.m{
   //    self.Add(v)
   // }
   // return self
   //不能改变集合A的范围
   union := NewHashSet()
   for v := range self.m{
      union.Add(v)
   }
   for v := range other.m{
      union.Add(v)
   }
   return union
}

//属于A且属于B的元素
func (self *HashSet) Intersect(other *HashSet) *HashSet {
   if other == nil || other.Len() == 0{
      return NewHashSet()
   }
   intsSet := NewHashSet()
   for v,_ := range other.m{
      if self.Contains(v){
         intsSet.Add(v)
      }
   }
   return intsSet
}

//属于A且不属于B的元素
func (self *HashSet) Difference(other *HashSet) *HashSet {
   diffSet := NewHashSet()
   if other == nil || other.Len() == 0{
      diffSet.Union(self)
   } else {
      for v := range self.m{
         if !other.Contains(v){
            diffSet.Add(v)
         }
      }
   }

   return diffSet
}

//集合A与集合B中所有不属于A∩B的元素的集合
func (self *HashSet) SymmetricDifference(other *HashSet) *HashSet {
   //此时A∩B=∅,A中所有元素均不属于空集
   // if other == nil || other.Len() == 0{
   //    return self
   // }
   // ints := self.Intersect(other)
   // //此时A∩B=∅,A为空或B为空,B为空前面已经判断,此时B不能为空,即A为空
   // if ints == nil || ints.Len() == 0 {
   //    return other
   // }
   //
   // unionSet := self.Union(other)
   // result := NewHashSet()
   // for v := range unionSet.m{
   //    if !ints.Contains(v){
   //       result.Add(v)
   //    }
   // }
   ints := self.Difference(other)
   union := self.Union(other)
   return union.Difference(ints)
}

测试代码

package main

import (
   "fmt"
   "qii/set"
)

func main()  {
   set1 := set.NewHashSet()
   set1.Add(1)
   set1.Add("e2")
   set1.Add(3)
   set1.Add("e4")
   fmt.Println("set1:", set1)
   fmt.Printf("set1 Elements:%v\n", set1.Elements())

   set2 := set.NewHashSet()
   set2.Add(3)
   set2.Add("e2")
   set2.Add(5)
   set2.Add("e6")

   fmt.Println("set2:", set1)
   fmt.Printf("set1 union set2:%v\n", set1.Union(set2))
   fmt.Printf("set1 intersect set2:%v\n", set1.Intersect(set2))
   fmt.Println(set1,set2)
   fmt.Printf("set1 difference set2:%v\n", set1.Difference(set2))
   fmt.Printf("set1 SymmetricDifference set2:%v\n", set1.SymmetricDifference(set2))
   set1.Clear()
   fmt.Println(set1)
}

 


有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:qii

查看原文:go之实现集合及操作

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2255 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传