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

本文介绍如何在Go语言中实现Set数据结构,利用Map来模拟Set的基本操作,如添加、删除元素等,并实现了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集合就完成了。

posted on 2017-01-11 09:25 bvac 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/bvac/p/6272355.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值