zoukankan      html  css  js  c++  java
  • 用bit数组构建集合

    用bit位来构建集合,查找插入重复数据效率都非常高。

    type IntSet struct {
        words []uint64
    }
    
    // Has reports whether the set contains the non-negative value x.
    func (s *IntSet) Has(x int) bool {
        word, bit := x/64, uint(x%64)
        return word < len(s.words) && s.words[word]&(1<<bit) != 0
    }
    
    // Add adds the non-negative value x to the set.
    func (s *IntSet) Add(x int) {
        word, bit := x/64, uint(x%64)
        for word >= len(s.words) {
            s.words = append(s.words, 0)
        }
        s.words[word] |= 1 << bit
    }
    
    // remove x
    func (s *IntSet) Remove(x int) int {
        word, bit := x/64, uint(x%64)
        if word >= len(s.words) {
            return -1 //不存在
        }
        s.words[word] &= ^(1 << bit)
        return 0
    }
    
    // UnionWith sets s to the union of s and t.
    func (s *IntSet) UnionWith(t *IntSet) {
        for i, tword := range t.words {
            if i < len(s.words) {
                s.words[i] |= tword
            } else {
                s.words = append(s.words, tword)
            }
        }
    }
    // 交集
    func (s *IntSet) InterWith(t *IntSet) {
        for i, tword := range t.words {
            if i < len(s.words) {
                s.words[i] &= tword
            }
        }
    }
    // 长度
    func (s *IntSet) Len() (len int) {
        for _, tword := range s.words {
            if tword == 0 {
                continue
            }
            for j := 0; j < 64; j++ {
                if tword&(1<<uint(j)) != 0 {
                    len++
                }
            }
        }
        return
    }
    // 转换成string,便于查看
    func (s *IntSet) String() string {
        var buf bytes.Buffer
        buf.WriteByte('{')
        for i, word := range s.words {
            if word == 0 {
                continue
            }
            for j := 0; j < 64; j++ {
                if word&(1<<uint(j)) != 0 { //判断这一位是否存在
                    if buf.Len() > len("{") { //不是第一位就加空格
                        buf.WriteByte(' ')
                    }
                    fmt.Fprintf(&buf, "%d", 64*i+j)
                }
            }
        }
        buf.WriteByte('}')
        return buf.String()
    }
    // 复制
    func (s *IntSet) Copy() (res *IntSet) {
        res = &IntSet{}
        res.words = make([]uint64, len(s.words))
        copy(res.words, s.words)
        return
    }
    // 清空
    func (s *IntSet) Clear() {
        for i := range s.words {
            s.words[i] &= 0
        }
    }

    以上算法都基于bit运算,包括与,或,异或

  • 相关阅读:
    redis概要学习
    http协议格式详解
    浅谈mysql
    linux常用命令
    Linux 程序管理
    认识与分析日志文件
    认识与学习bash
    例行任务管理
    软件安装的三大方法
    关于一些感慨
  • 原文地址:https://www.cnblogs.com/peterleee/p/13892030.html
Copyright © 2011-2022 走看看