问题:假设有500w条数据,数据是在2^32-1的范围内,数据重复,如何减少内存对数字进行统计呢?

  如果用字典来标记数字是否已经统计过来,数字做为key, value仅为0 or1,那么这样需要消耗

内存32*500w+32*500w,key和value占用内存相加。

  但如果我们用value的位来标记数据是否统计过,32bit可以存32个不同的数字,这样可以减少

为500w/32+500w/32.这就是bit bucket的魅力所在。

#!/usr/bin/env python
#-*- coding:utf-8 -*- SHIFT = 5 # 如果计算机为32位,SHIFT为5;如果计算机为64位,SHIFT为6
MASK = 0x1F # 如果计算机为32位,MASK为0x1F;如果计算机为64位,MASK为0x3F class BitBucket(object):
def __init__(self):
self._unique_key_count = 0 # 唯一的key有多少个
self._total_key_count = 0 # 加入的key有多少个
self._bit = {} def set(self, value):
"""return last bit"""
self._total_key_count += 1 if not self._has_key(value):
self._unique_key_count += 1
key = value >> SHIFT
self._bit[key] = self._bit.get(key, 0) | (1 << (value & MASK))
return 0
return 1 def exist(self, value):
if self._has_key(value):
return True
return False def clear(self, value):
if self._has_key(value):
self._unique_key_count -= 1
self._total_key_count -= 1 key = value >> SHIFT
self._bit[key] = self._bit[key] & (~(1 << (value & MASK)))
return True
return False def get_total_count(self):
return self._total_key_count def get_bit_count(self):
return self._unique_key_count def _has_key(self, value):
key = value >> SHIFT
return self._bit.get(key, 0) & (1 << (value & MASK)) if __name__ == '__main__':
bitBucket = BitBucket() for i in range(1, 27):
bitBucket.set(i) print bitBucket.get_total_count()
print bitBucket.get_bit_count() count = 0
for i in range(1, 30):
if bitBucket.exist(i):
count += 1 assert count == bitBucket.get_bit_count()

位图bitbucket的更多相关文章

  1. SQLSERVER中NULL位图的作用

    SQLSERVER中NULL位图的作用 首先感谢宋沄剑提供的文章和sqlskill网站:www.sqlskills.com,看下面文章之前请先看一下下面两篇文章 SQL Server误区30日谈-Da ...

  2. Oracle位图索引

    索引由KEY和Data组成 位图索引的KEY比普通非唯一性索引多包含一个组成部分,分区,分区是将数据按行由内部机制分段以达到比较好的检索效率 位图索引的Data中,该索引KEY中数据值在分区段中按行分 ...

  3. 基于位图(Bitmap、BitmapData)的图片处理方法(C#)

    目前操作位图的主流方法有三种: 1.基于Bitmap像素的处理方法,以GetPixel()和SetPixel()方法为主.方法调用简单,但是效率偏低. 2.基于内存的像素操作方法,以System.Ru ...

  4. 【读书笔记】《编程珠玑》第一章之位向量&位图

    此书的叙述模式是借由一个具体问题来引出的一系列算法,数据结构等等方面的技巧性策略.共分三篇,基础,性能,应用.每篇涵盖数章,章内案例都非常切实棘手,解说也生动有趣. 自个呢也是头一次接触编程技巧类的书 ...

  5. Atitit 索引技术--位图索引

    Atitit 索引技术--位图索引 索引在数据结构上可以分为三种B树索引.位图索引和散列索引 存储原理 编辑 位图索引对数据表的列的每一个键值分别存储为一个位图,Oracle对于不同的版本,不同的操作 ...

  6. DIB位图(Bitmap)的读取和保存

    设备无关位图(Device Independent Bitmap)是可以保存在磁盘的位图文件,可以从磁盘读取到内存或者从内存保存到磁盘上.它的文件结构是标准化的,可以在Windows/Linux/Un ...

  7. Oracle索引梳理系列(四)- Oracle索引种类之位图索引

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  8. 用Bitbucket搭建博客初探

    本博客是搭建在GitHub上的静态博客,但是由于GitHub免费账户不能创建私有仓库,导致有些东西不想放在GitHub上. 前两天,在免费资源部落上发现了Bitbucket,它和GitHub类似,也是 ...

  9. Quartz2D 编程指南(四)位图与图像遮罩、CoreGraphics 绘制 Layer

    概览 图形上下文 路径 颜色与颜色空间 变换 图案 阴影 渐变 透明层 Quartz 2D 中的数据管理 位图与图像遮罩 CoreGraphics 绘制 Layer 位图与图像遮罩 简介 位图与图像遮 ...

随机推荐

  1. golang语言中os/exec包的学习与使用

    package main; import ( "os/exec" "fmt" "io/ioutil" "bytes" ) ...

  2. 半吊子的STM32 — IIC通信

    半双工通信模式:以字节模式发送(8位): 两线式串行总线,SDA(数据信号)和SCL(时钟信号)两条信号线都为高电平时,总线为空闲状态:起始时,SCL稳定为高电平,SDA电平由高向低跳变:停止时,SC ...

  3. rem初始化

    使用css实现rem适配,头部引入即可 adaptive.js !function(e, t) { function i() { o = , e.devicePixelRatioValue = o, ...

  4. PopupWindow与Edittext结合使用所遇到的坑

    PopupWindow与Edittext结合使用一起实现目的:既可以编辑输入想要的内容,还可以通过下拉列表来实现内容的选择. 我就是这样的一个目的,结果很简单的目的却遇到了很大的坑,下面我将把我遇到的 ...

  5. 2018 How to register and install LAUNCH ICARSCAN software ?

    2018 New Version ICARSCAN is available now! Here’s the instruction on how to install ICARSCAN softwa ...

  6. CURLOPT_RETURNTRANSFER

    curl_setopt($ch,CURLOPT_RETURNTRANSFER,);//设置返回值不直接输出,例如返回xml格式,会将xml原样输出

  7. JSR 规范目录

    JSR 规范目录 一.Servlet 规范 1.1 Servlet 2.x 规范 1.2 Servlet 3.x 规范 - 注解和异步请求规范 每天用心记录一点点.内容也许不重要,但习惯很重要!

  8. Ionic学习

    1. 原来Http不能直接加在普通类里,下面的报错 import { Component } from '@angular/core'; import { NavController } from ' ...

  9. is not allowed to connect to this MySQL server解决办法

    GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%' IDENTIFIED BY 'mypassword' WITH GRANT OPTION; myuser:代表你 ...

  10. idea+tomcat 端口占用

    ntelliJ IDEA和Tomcat整合注意事项(转) 这两天一直在学习IDEA这个开发工具,今天再整合tomcat的时候遇到了问题,运行时总是报错,说是8080端口被占用,把我就搞的郁闷了,我就尝 ...