zoukankan      html  css  js  c++  java
  • 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集合就完成了。

  • 相关阅读:
    模块和包——Python
    异常——Python
    单例——Python
    类属性和类方法——Python
    继承和多态——Python
    私有属性和私有方法——Python
    面向对象封装案例——Python
    面相对象基础语法——Python
    类、接口作为成员变量类型——Java
    内部类的概念和分类——Java
  • 原文地址:https://www.cnblogs.com/bvac/p/6272355.html
Copyright © 2011-2022 走看看