set.go

// set project set.go
package settype Set interface {Add(e interface{}) boolRemove(e interface{})Clear()Contains(e interface{}) boolLen() intSame(other Set) boolElements() []interface{}String() string
}// 将集合other添加到集合one中
func AddSet(one Set, other Set) {if one == nil || other == nil || other.Len() == 0 {return}for _, v := range other.Elements() {one.Add(v)}
}// 判断集合 one 是否是集合 other 的超集
func IsSuperset(one Set, other Set) bool {if one == nil || other == nil {return false}oneLen := one.Len()otherLen := other.Len()if oneLen == 0 || oneLen <= otherLen {return false}if oneLen > 0 && otherLen == 0 {return true}for _, v := range other.Elements() {if !one.Contains(v) {return false}}return true
}// 生成集合 one 和集合 other 的并集
func Union(one Set, other Set) Set {if one == nil && other == nil {return nil}unionedSet := NewSimpleSet()AddSet(unionedSet, one)AddSet(unionedSet, other)return unionedSet
}// 生成集合 one 和集合 other 的交集
func Intersect(one Set, other Set) Set {if one == nil || other == nil {return nil}intersectedSet := NewSimpleSet()if one.Len() == 0 || 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
}// 生成集合 one 对集合 other 的差集
func Difference(one Set, other Set) Set {if one == nil {return nil}differencedSet := NewSimpleSet()if other == nil || other.Len() == 0 {AddSet(differencedSet, one)return differencedSet}for _, v := range one.Elements() {if !other.Contains(v) {differencedSet.Add(v)}}return differencedSet
}// 生成集合 one 和集合 other 的对称差集
func SymmetricDifference(one Set, other Set) Set {diffA := Difference(one, other)if other == nil || other.Len() == 0 {return diffA}diffB := Difference(other, one)return Union(diffA, diffB)
}// 返回一个HashSet
func NewSimpleSet() Set {return NewHashSet()
}// 判断给定value是否为集合
func IsSet(value interface{}) bool {if _, ok := value.(Set); ok {return true}return false
}

hash_set.go

// hash_set
package setimport ("bytes""fmt"
)type HashSet struct {m map[interface{}]bool
}// 创建和初始化HashSet的方法
func NewHashSet() *HashSet {return &HashSet{m: make(map[interface{}]bool)}
}// 向HashSet中添加元素的方法
func (set *HashSet) Add(e interface{}) bool {if !set.m[e] {set.m[e] = truereturn true}return false
}// 删除HashSet中指定的元素
func (set *HashSet) Remove(e interface{}) {delete(set.m, e)
}// 清除HashSet中的所有元素
func (set *HashSet) Clear() {set.m = make(map[interface{}]bool)
}// 判断HashSet是否包含指定元素
func (set *HashSet) Contains(e interface{}) bool {return set.m[e]
}// 获取HashSet中元素值数量
func (set *HashSet) Len() int {return len(set.m)
}// 判断两个Set类型值是否相同
func (set *HashSet) Same(other Set) bool {if other == nil {return false}if set.Len() != other.Len() {return false}for key := range set.m {if !other.Contains(key) {return false}}return true
}// 生成HashSet的一个快照
func (set *HashSet) Elements() []interface{} {initialLen := len(set.m)snapshot := make([]interface{}, initialLen)actualLen := 0for key := range set.m {if actualLen < initialLen {snapshot[actualLen] = key} else {snapshot = append(snapshot, key)}actualLen++}if actualLen < initialLen {snapshot = snapshot[:actualLen]}return snapshot
}// 获取HashSet自身字符串表示形式
func (set *HashSet) String() string {var buf bytes.Bufferbuf.WriteString("Set{")first := truefor key := range set.m {if first {first = false} else {buf.WriteString(" ")}buf.WriteString(fmt.Sprintf("%v", key))}buf.WriteString("}")return buf.String()
}

功能测试:

set_test.go

// set_test
package setimport ("bytes""fmt""math/rand""runtime/debug""strings""testing""time"
)func testSetLenAndContains(t *testing.T, newSet func() Set, typeName string) {t.Logf("Starting Test%sLenAndContains...", typeName)set, expectedElemMap := genRandSet(newSet)t.Logf("Got a %s value: %v.", typeName, set)expectedLen := len(expectedElemMap)if set.Len() != expectedLen {t.Errorf("ERROR: The length of %s value %d is not %d!\n",set.Len(), typeName, expectedLen)t.FailNow()}t.Logf("The length of %s value is %d.\n", typeName, set.Len())for k := range expectedElemMap {if !set.Contains(k) {t.Errorf("ERROR: The %s value %v do not contains %v!",set, typeName, k)t.FailNow()}}
}func testSetAdd(t *testing.T, newSet func() Set, typeName string) {t.Logf("Starting Test%sAdd...", typeName)set := newSet()var randElem interface{}var result boolexpectedElemMap := make(map[interface{}]bool)for i := 0; i < 5; i++ {randElem = genRandElement()t.Logf("Add %v to the %s value %v.\n", randElem, typeName, set)result = set.Add(randElem)if expectedElemMap[randElem] && result {t.Errorf("ERROR: The element adding (%v => %v) is successful but should be failing!\n",randElem, set)t.FailNow()}if !expectedElemMap[randElem] && !result {t.Errorf("ERROR: The element adding (%v => %v) is failing!\n",randElem, set)t.FailNow()}expectedElemMap[randElem] = true}t.Logf("The %s value: %v.", typeName, set)expectedLen := len(expectedElemMap)if set.Len() != expectedLen {t.Errorf("ERROR: The length of %s value %d is not %d!\n",set.Len(), typeName, expectedLen)t.FailNow()}t.Logf("The length of %s value is %d.\n", typeName, set.Len())for k := range expectedElemMap {if !set.Contains(k) {t.Errorf("ERROR: The %s value %v do not contains %v!",set, typeName, k)t.FailNow()}}
}func testSetRemove(t *testing.T, newSet func() Set, typeName string) {t.Logf("Starting Test%sRemove...", typeName)set, expectedElemMap := genRandSet(newSet)t.Logf("Got a %s value: %v.", typeName, set)t.Logf("The length of %s value is %d.\n", typeName, set.Len())var number intfor k, _ := range expectedElemMap {if number%2 == 0 {t.Logf("Remove %v from the HashSet value %v.\n", k, set)set.Remove(k)if set.Contains(k) {t.Errorf("ERROR: The element removing (%v => %v) is failing!\n",k, set)t.FailNow()}delete(expectedElemMap, k)}number++}expectedLen := len(expectedElemMap)if set.Len() != expectedLen {t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", set.Len(), expectedLen)t.FailNow()}t.Logf("The length of %s value is %d.\n", typeName, set.Len())for _, v := range set.Elements() {if !expectedElemMap[v] {t.Errorf("ERROR: The HashSet value %v contains %v but should not contains!", set, v)t.FailNow()}}
}func testSetClear(t *testing.T, newSet func() Set, typeName string) {t.Logf("Starting Test%sClear...", typeName)set, _ := genRandSet(newSet)t.Logf("Got a %s value: %v.", typeName, set)t.Logf("The length of %s value is %d.\n", typeName, set.Len())t.Logf("Clear the HashSet value %v.\n", set)set.Clear()expectedLen := 0if set.Len() != expectedLen {t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", set.Len(), expectedLen)t.FailNow()}t.Logf("The length of %s value is %d.\n", typeName, set.Len())
}func testSetElements(t *testing.T, newSet func() Set, typeName string) {t.Logf("Starting Test%sElements...", typeName)set, expectedElemMap := genRandSet(newSet)t.Logf("Got a %s value: %v.", typeName, set)t.Logf("The length of %s value is %d.\n", typeName, set.Len())elems := set.Elements()t.Logf("The elements of %s value is %v.\n", typeName, elems)expectedLen := len(expectedElemMap)if len(elems) != expectedLen {t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", len(elems), expectedLen)t.FailNow()}t.Logf("The length of elements is %d.\n", len(elems))for _, v := range elems {if !expectedElemMap[v] {t.Errorf("ERROR: The elements %v contains %v but should not contains!", set, v)t.FailNow()}}
}func testSetSame(t *testing.T, newSet func() Set, typeName string) {t.Logf("Starting Test%sSame...", typeName)set, _ := genRandSet(newSet)t.Logf("Got a %s value: %v.", typeName, set)t.Logf("The length of %s value is %d.\n", typeName, set.Len())set2 := newSet()t.Logf("Clone the HashSet value %v...\n", set)for _, v := range set.Elements() {set2.Add(v)}result := set2.Same(set)if !result {t.Errorf("ERROR: Two sets are not same!")}t.Logf("Two sets are same.")
}func testSetString(t *testing.T, newSet func() Set, typeName string) {t.Logf("Starting Test%sString...", typeName)set, _ := genRandSet(newSet)t.Logf("Got a %s value: %v.", typeName, set)setStr := set.String()t.Logf("The string of %s value is %s.\n", typeName, setStr)var elemStr stringfor _, v := range set.Elements() {elemStr = fmt.Sprintf("%v", v)if !strings.Contains(setStr, elemStr) {t.Errorf("ERROR: The string of %s value %s do not contains %s!",typeName, setStr, elemStr)t.FailNow()}}
}// ----- Set 公用函数测试 -----

func TestIsSuperset(t *testing.T) {defer func() {if err := recover(); err != nil {debug.PrintStack()t.Errorf("Fatal Error: %s\n", err)}}()t.Log("Starting TestIsSuperset...")set, _ := genRandSet(func() Set { return NewSimpleSet() })set2 := NewSimpleSet()for _, v := range set.Elements() {set2.Add(v)}for extraElem := genRandElement(); ; {if set2.Add(extraElem) {break} else {time.Sleep(10 * time.Millisecond)}}if !IsSuperset(set2, set) {t.Errorf("ERROR: The HashSet value %v is not a superset of %v!\n", set2, set)t.FailNow()} else {t.Logf("The HashSet value %v is a superset of %v.\n", set2, set)}for extraElem := genRandElement(); ; {if set.Add(extraElem) {break} else {time.Sleep(10 * time.Millisecond)}}if IsSuperset(set2, set) {t.Errorf("ERROR: The HashSet value %v should not be a superset of %v!\n", set2, set)t.FailNow()} else {t.Logf("The HashSet value %v is not a superset of %v.\n", set2, set)}
}func TestUnion(t *testing.T) {defer func() {if err := recover(); err != nil {debug.PrintStack()t.Errorf("Fatal Error: %s\n", err)}}()t.Log("Starting TestUnion...")set, _ := genRandSet(func() Set { return NewSimpleSet() })t.Logf("The set value: %v", set)set2, _ := genRandSet(func() Set { return NewSimpleSet() })uSet := Union(set, set2)t.Logf("The set value (2): %v", set2)for _, v := range set.Elements() {if !uSet.Contains(v) {t.Errorf("ERROR: The union set value %v do not contains %v!",uSet, v)t.FailNow()}}for _, v := range set2.Elements() {if !uSet.Contains(v) {t.Errorf("ERROR: The union set value %v do not contains %v!",uSet, v)t.FailNow()}}t.Logf("The set value %v is a unioned set of %v and %v", uSet, set, set2)
}func TestIntersect(t *testing.T) {defer func() {if err := recover(); err != nil {debug.PrintStack()t.Errorf("Fatal Error: %s\n", err)}}()t.Log("Starting TestIntersect...")commonElem := genRandElement()set, _ := genRandSet(func() Set { return NewSimpleSet() })set.Add(commonElem)t.Logf("The set value: %v", set)set2, _ := genRandSet(func() Set { return NewSimpleSet() })set2.Add(commonElem)t.Logf("The set value (2): %v", set2)iSet := Intersect(set, set2)for _, v := range iSet.Elements() {if !set.Contains(v) {t.Errorf("ERROR: The set value %v do not contains %v!",set, v)t.FailNow()}if !set2.Contains(v) {t.Errorf("ERROR: The set value %v do not contains %v!",set2, v)t.FailNow()}}t.Logf("The set value %v is a intersected set of %v and %v", iSet, set, set2)
}func TestDifference(t *testing.T) {defer func() {if err := recover(); err != nil {debug.PrintStack()t.Errorf("Fatal Error: %s\n", err)}}()t.Log("Starting TestDifference...")commonElem := genRandElement()set, _ := genRandSet(func() Set { return NewSimpleSet() })set.Add(commonElem)t.Logf("The set value: %v", set)set2, _ := genRandSet(func() Set { return NewSimpleSet() })set2.Add(commonElem)t.Logf("The set value (2): %v", set2)dSet := Difference(set, set2)for _, v := range dSet.Elements() {if !set.Contains(v) {t.Errorf("ERROR: The set value %v do not contains %v!",set, v)t.FailNow()}if set2.Contains(v) {t.Errorf("ERROR: The set value %v contains %v!",set2, v)t.FailNow()}}t.Logf("The set value %v is a differenced set of %v to %v", dSet, set, set2)
}func TestSymmetricDifference(t *testing.T) {defer func() {if err := recover(); err != nil {debug.PrintStack()t.Errorf("Fatal Error: %s\n", err)}}()t.Log("Starting TestSymmetricDifference...")commonElem := genRandElement()set, _ := genRandSet(func() Set { return NewSimpleSet() })set.Add(commonElem)t.Logf("The set value: %v", set)set2, _ := genRandSet(func() Set { return NewSimpleSet() })set2.Add(commonElem)t.Logf("The set value (2): %v", set2)sdSet := SymmetricDifference(set, set2)for _, v := range sdSet.Elements() {if set.Contains(v) && set2.Contains(v) {t.Errorf("ERROR: The element %v can not be a common element of %v to %v!",v, set, set2)t.FailNow()}}t.Logf("The set value %v is a symmetric differenced set of %v to %v", sdSet, set, set2)
}// ----- 随机测试对象生成函数 -----

func genRandSet(newSet func() Set) (set Set, elemMap map[interface{}]bool) {set = newSet()elemMap = make(map[interface{}]bool)var enough boolfor !enough {e := genRandElement()set.Add(e)elemMap[e] = trueif len(elemMap) >= 3 {enough = true}}return
}func genRandElement() interface{} {seed := rand.Int63n(10000)switch seed {case 0:return genRandInt()case 1:return genRandString()case 2:return struct {num int64str string}{genRandInt(), genRandString()}default:const length = 2arr := new([length]interface{})for i := 0; i < length; i++ {if i%2 == 0 {arr[i] = genRandInt()} else {arr[i] = genRandString()}}return *arr}
}func genRandString() string {var buff bytes.Buffervar prev stringvar curr stringfor i := 0; buff.Len() < 3; i++ {curr = string(genRandAZAscii())if curr == prev {continue} else {prev = curr}buff.WriteString(curr)}return buff.String()
}func genRandAZAscii() int {min := 65 // Amax := 90 // Z
    rand.Seed(time.Now().UnixNano())return min + rand.Intn(max-min)
}func genRandInt() int64 {return rand.Int63n(10000)
}

hash_set_test.go

// hash_set_test
package setimport ("fmt""runtime/debug""strings""testing"
)func TestHashSetCreation(t *testing.T) {defer func() {if err := recover(); err != nil {debug.PrintStack()t.Errorf("Fatal Error: %s\n", err)}}()t.Log("Starting TestHashSetCreation...")hs := NewHashSet()t.Logf("Create a HashSet value: %v\n", hs)if hs == nil {t.Errorf("The result of func NewHashSet is nil!\n")}isSet := IsSet(hs)if !isSet {t.Errorf("The value of HashSet is not Set!\n")} else {t.Logf("The HashSet value is a Set.\n")}
}func TestHashSetLenAndContains(t *testing.T) {testSetLenAndContains(t, func() Set { return NewHashSet() }, "HashSet")
}func TestHashSetAdd(t *testing.T) {testSetAdd(t, func() Set { return NewHashSet() }, "HashSet")
}func TestHashSetRemove(t *testing.T) {testSetRemove(t, func() Set { return NewHashSet() }, "HashSet")
}func TestHashSetClear(t *testing.T) {testSetClear(t, func() Set { return NewHashSet() }, "HashSet")
}func TestHashSetElements(t *testing.T) {testSetElements(t, func() Set { return NewHashSet() }, "HashSet")
}func TestHashSetSame(t *testing.T) {testSetSame(t, func() Set { return NewHashSet() }, "HashSet")
}func TestSetString(t *testing.T) {testSetString(t, func() Set { return NewHashSet() }, "HashSet")
}func testSetOp(t *testing.T) {defer func() {if err := recover(); err != nil {debug.PrintStack()t.Errorf("Fatal Error: %s\n", err)}}()fmt.Println(222)t.Logf("Starting TestHashSetOp...")hs := NewHashSet()if hs.Len() != 0 {t.Errorf("ERROR: The length of original HashSet value is not 0!\n")t.FailNow()}randElem := genRandElement()expectedElemMap := make(map[interface{}]bool)t.Logf("Add %v to the HashSet value %v.\n", randElem, hs)hs.Add(randElem)expectedElemMap[randElem] = trueexpectedLen := len(expectedElemMap)if hs.Len() != expectedLen {t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", hs.Len(), expectedLen)t.FailNow()}var result boolfor i := 0; i < 8; i++ {randElem = genRandElement()t.Logf("Add %v to the HashSet value %v.\n", randElem, hs)result = hs.Add(randElem)if expectedElemMap[randElem] && result {t.Errorf("ERROR: The element adding (%v => %v) is successful but should be failing!\n",randElem, hs)t.FailNow()}if !expectedElemMap[randElem] && !result {t.Errorf("ERROR: The element adding (%v => %v) is failing!\n",randElem, hs)t.FailNow()}expectedElemMap[randElem] = true}expectedLen = len(expectedElemMap)if hs.Len() != expectedLen {t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", hs.Len(), expectedLen)t.FailNow()}for k, _ := range expectedElemMap {if !hs.Contains(k) {t.Errorf("ERROR: The HashSet value %v do not contains %v!", hs, k)t.FailNow()}}number := 2for k, _ := range expectedElemMap {if number%2 == 0 {t.Logf("Remove %v from the HashSet value %v.\n", k, hs)hs.Remove(k)if hs.Contains(k) {t.Errorf("ERROR: The element adding (%v => %v) is failing!\n",randElem, hs)t.FailNow()}delete(expectedElemMap, k)}number++}expectedLen = len(expectedElemMap)if hs.Len() != expectedLen {t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", hs.Len(), expectedLen)t.FailNow()}for _, v := range hs.Elements() {if !expectedElemMap[v] {t.Errorf("ERROR: The HashSet value %v contains %v!", hs, v)t.FailNow()}}hs2 := NewHashSet()for k, _ := range expectedElemMap {hs2.Add(k)}if !hs.Same(hs2) {t.Errorf("ERROR: HashSet value %v do not same %v!\n", hs, hs2)t.FailNow()}str := hs.String()t.Logf("The string of HashSet value %v is '%s'.\n", hs, str)for _, v := range hs.Elements() {if !strings.Contains(str, fmt.Sprintf("%v", v)) {t.Errorf("ERROR: '%s' do not contains '%v'!", str, v)t.FailNow()}}
}

转载于:https://www.cnblogs.com/gaopeng527/p/6154977.html

Go语言实现HashSet相关推荐

  1. C语言实现hashset算法(附完整源码)

    C语言实现hashset算法 完整hash_set.h 头文件 完整hash_set.c 源文件 完整hashset算法(main测试函数) 完整hash_set.h 头文件 #ifndef __HA ...

  2. C和C++算法完整教程专栏完整目录

    C和C++算法完整教程专栏完整目录 专栏说明如下 完整专栏目录如下 专栏说明如下 内容:C和C++算法完整教程 数量:680篇博文(2023年2月15日截止) 更新时间至:2023年2月15日(后续加 ...

  3. (一)redis常见5种数据结构

    目录 官网介绍(https://redis.io/) Redis 优势 Redis 数据类型 string hash list set Zset 小总结 官网介绍(https://redis.io/) ...

  4. ajax 自动清缓存,ajax 清除缓存

    $.ajax({ url : actionUrl , beforeSend :function(xmlHttp){  // deforeSend 是请求前清除缓存  ,如果没有缓存也不使用before ...

  5. 巧用HashSet装载非重数据(洛谷P2250题题解,Java语言描述)

    题目要求 P2550题目链接 分析 其实既然是Java来写,不用集合框架就是浪费啊!! 比较简单的思路是把中奖号码放进HashSet里,利用Hash来查找. contains()就避免了又双叒叕疯狂遍 ...

  6. LeetCode刷题记录13——705. Design HashSet(easy)

    LeetCode刷题记录13--705. Design HashSet(easy) 目录 LeetCode刷题记录13--705. Design HashSet(easy) 前言 题目 语言 思路 源 ...

  7. Hash+哈希表+HashMap+HashSet

    Hash+哈希表+HashMap+HashSet 哈希算法,是一类「算法」. 哈希表(Hash Table),是一种「数据结构」. 哈希函数,是支撑哈希表的一类「函数」. Map是映射/地图的意思,在 ...

  8. Scala语言编写的爬虫应用-爬取一部小说

    这几天使用手机看玄幻小说<斗罗大陆3-龙王传说>,页面总是弹出色色的广告,不但浪费了流量延迟了加载时间,而且严重影响心情,决定写一个爬虫爬取该网站的小说部分的内容,把它保存成txt格式,直 ...

  9. 雷卷 java,阿里巴巴资深技术专家雷卷:值得开发者关注的 Java 8 后时代的语言特性...

    阿里巴巴资深技术专家雷卷:值得开发者关注的 Java 8 后时代的语言特性 发布时间:2020-07-04 08:25:36 来源:51CTO 阅读:315 作者:阿里系统软件技术 栏目:云计算 作者 ...

最新文章

  1. 利用卷积神经网络对脑电图解码及可视化
  2. 一步一步学Silverlight 2系列(32):图形图像综合实例—“功夫之王”剧照播放_转载...
  3. Spring表单的initBinder:绑定表单复杂属性
  4. 【[网络流二十四题]最长不下降子序列问题】
  5. 15.确保“lessT“与“operator小于“具有相同的语义
  6. 在Chrome插件上获取当前插件的版本号
  7. 远程仓库---添加远程库
  8. Direct3D中的绘制(3)
  9. VMware vSphere Client下增加虚拟机磁盘空间的方法
  10. 苹果 M1带起ARM,英特尔 x86 霸主地位遭威胁
  11. 字符串替换(NYOJ)
  12. SSh框架的整合流程
  13. 高等数学(第七版)同济大学 习题4-4(后14题) 个人解答
  14. Android_JNI编程入门
  15. java exif_Java读取图片EXIF信息的方法
  16. 嫁给年薪百万的程序员,结婚 6 年后的我竟然还是处女
  17. 不得不说,这19个程序员兼职平台让我1年收入60w
  18. java课后思考问题(八)
  19. springboot考研规划系统 毕业设计-附源码541230
  20. Revit建模中如何快速画好幕墙?

热门文章

  1. mysql 4字节utf8_MySQL 4字节utf8字符更新失败一例
  2. java tm无响应_Java(TM) Platform SE binary 未响应 是怎么个情况?
  3. python模拟密码有效性检测功能_检查密码有效性(Django/Python)
  4. ibm+x3650+m4+linux+raid驱动,IBM X3650M4阵列卡驱动下载
  5. protected访问权限_权限修饰符 /重写
  6. dataframe转化为array_【Python专栏】12 种高效 Numpy 和 Pandas 函数为你加速分析
  7. JSP中Request属性范围
  8. java警惕自增的陷阱
  9. 160 - 45 Dope2112.2
  10. ffmpeg 命令画中画效果