Golang实现集合(set)
- package set
package set import (
"bytes"
"fmt"
"sync"
) type Set struct {
m map[interface{}]bool
sync.RWMutex
} func New() *Set {
return &Set{m: make(map[interface{}]bool)}
} func (self *Set) Add(e interface{}) bool {
self.Lock()
defer self.Unlock()
if self.m[e] {
return false
}
self.m[e] = true
return true
} func (self *Set) Remove(e interface{}) bool {
self.Lock()
defer self.Unlock()
delete(self.m, e)
return true
} func (self *Set) Clear() bool {
self.Lock()
defer self.Unlock()
self.m = make(map[interface{}]bool)
return true
} func (self *Set) Contains(e interface{}) bool {
self.Lock()
defer self.Unlock()
//return self.m[e]
_, ok := self.m[e]
return ok
} func (self *Set) IsEmpty() bool {
return self.Len() == 0
} func (self *Set) Len() int {
self.Lock()
defer self.Unlock()
return len(self.m)
} func (self *Set) Same(other *Set) 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 *Set) Elements() interface{} {
self.Lock()
defer self.Unlock()
// 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 *Set) String() string {
self.Lock()
defer self.Unlock()
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 *Set) IsSuperSet(other *Set) bool {
self.Lock()
defer self.Unlock()
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 *Set) Union(other *Set) *Set {
self.Lock()
defer self.Unlock()
// if other == nil || other.Len() == 0{
// return self
// }
//
// for v := range other.m{
// self.Add(v)
// }
// return self
//不能改变集合A的范围
union := New()
for v := range self.m {
union.Add(v)
}
for v := range other.m {
union.Add(v)
}
return union
} //属于A且属于B的元素
func (self *Set) Intersect(other *Set) *Set {
self.Lock()
defer self.Unlock()
if other == nil || other.Len() == 0 {
return New()
}
intsSet := New()
for v, _ := range other.m {
if self.Contains(v) {
intsSet.Add(v)
}
}
return intsSet
} //属于A且不属于B的元素
func (self *Set) Difference(other *Set) *Set {
self.Lock()
defer self.Unlock()
diffSet := New()
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 *Set) SymmetricDifference(other *Set) *Set {
self.Lock()
defer self.Unlock()
//此时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 := New()
// for v := range unionSet.m{
// if !ints.Contains(v){
// result.Add(v)
// }
// }
ints := self.Difference(other)
union := self.Union(other)
return union.Difference(ints)
}
- main.go
package main import (
"fmt"
"go_dev/go_set/set"
) func main() {
setTest()
} func setTest() {
set1 := set.New()
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.New()
set2.Add(3)
set2.Add("e2")
set2.Add(5)
set2.Add("e6") fmt.Println("set2:", set2)
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)
}
Golang实现集合(set)的更多相关文章
- 代码片段 - Golang 实现集合操作
------------------------------------------------------------ 如果用于多例程,可以使用下面的版本: -------------------- ...
- Golang 实现 set 集合,变相实现 切片去重、排序 功能
Java 中的集合(set)去重很方便,PHP 中的数组值去重,就更加方便,一个函数搞定:array_unique(),Golang 中就比较苦逼了,官方没有提供对“切片去重”的功能,而项目中,又经常 ...
- golang map
Our friend Monk has been made teacher for the day today by his school professors . He is going to te ...
- golang 在 windows 下编译出 linux 二进制可执行文件的软件套装合集 [go 1.7.3环境]
golang 很好用,不过要把工具链弄完整. 要不你会发现怎么不能编译跨平台的呀? 怎么写代码没提示啊? ... 这一整套弄下来并不容易. 所以精心准备了一套工具方便大家使用. 软件列表如图. 安装顺 ...
- GoLang基础数据类型--->字典(map)详解
GoLang基础数据类型--->字典(map)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 可能大家刚刚接触Golang的小伙伴都会跟我一样,这个map是干嘛的,是 ...
- GO语言的进阶之路-Golang高级数据结构定义
GO语言的进阶之路-Golang高级数据结构定义 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们之前学习过Golang的基本数据类型,字符串和byte,以及rune也有所了解, ...
- Golang资料集
<Platform-native GUI library for Go> 介绍:跨平台的golang GUI库,支持Windows(xp以上),Unix,Mac OS X(Mac OS X ...
- java基础-迭代器(Iterator)与增强for循环
java基础-迭代器(Iterator)与增强for循环 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Iterator迭代器概述 Java中提供了很多个集合,它们在存储元素时 ...
- golang实现常用集合原理介绍
golang本身对常用集合的封装还是比较少的,主要有数组(切片).双向链表.堆等.在工作中可能用到其他常用的集合,于是我自己对常用的集合进行了封装,并对原理做了简单介绍,代码库地址:https://g ...
随机推荐
- 【Java】【学习】【监听器】Listener的学习的案例(窗体程序)
JavaWeb 监听器listener 学习与简单应用 Java窗体程序使用监听器 效果:点击按钮,控制台出现文字 代码如下 import javax.swing.*; import java.awt ...
- Linux 01 计算机硬件之冯诺依曼体系
1. 计算机硬件软件体系 1.1 冯诺依曼体系结构 (1) 计算机处理的数据和指令用二进制表示 (2) 按顺序执行指令 (3) 计算机硬件:运算器.控制器.储存器.输入设备和输出设备. 1.2 计算机 ...
- [BUUCTF]PWN——[V&N2020 公开赛]warmup
[V&N2020 公开赛]warmup 附件 步骤: 例行检查,64位程序,除了canary,其他保护都开 本地运行一下,看看大概的情况 64位ida载入,从main函数开始看程序 看到程序将 ...
- LuoguP7369 [COCI2018-2019#4] Elder 题解
Content 有一个魔杖最初在 \(Z\) 巫师中.经过 \(n\) 轮较量,第 \(i\) 轮中,\(Z_{i,1}\) 巫师打败了 \(Z_{i,2}\) 巫师.如果一个巫师打败了拥有魔杖的巫师 ...
- echarts map 地图在react项目中的使用
需求 展示海南省地图,点击市高亮展示,并在右侧展示对应市的相关数据. 准备工作 Echarts 海南地图json 效果图 代码 index.tsx import React, { useRef, us ...
- JAVA实现查询栏目、类别(菜单)返回树结构(递归)
其中Channel.java是栏目结构,ChannelDto是我自己封装的返回给前端的数据,可以根据自己的来 这个的逻辑就是双重循环遍历每个类别,然后判断如果当前类别是其他类别的父级,那么就把其他类别 ...
- 【Android开发】找乐,一个笑话App的制作过程记录
缘起 想做一个笑话App的原因是因为在知乎上看过一个帖子,做Android可以有哪些数据可以练手,里面推荐了几个数据开放平台.在这些平台中无一不是有公共的笑话接口,当时心想这个可以拿来练手啊,还挺有意 ...
- Win8/Win10 Ctrl+Alt+方向键 屏幕显示翻转解决办法
状况 Win10系统下,在Android Studio中使用快捷键 Ctrl + Alt + ↓ 复制代码段的时候神奇的情况出现了,屏幕显示倒转了,我也只能是一脸懵逼,Win7下没有这个问题.经验判断 ...
- 【LeetCode】977. Squares of a Sorted Array 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 排序 日期 题目地址:https://leetcod ...
- 【LeetCode】61. Rotate List 解题报告(Python)
[LeetCode]61. Rotate List 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fux ...