zoukankan      html  css  js  c++  java
  • Redis学习笔记二 (BitMap算法分析与BitCount语法)

    Redis学习笔记二

    一、BitMap是什么

     

    就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间。

    二、BitMap算法基本描述

    BitMap 是使用 bit位来标记某个元素对应的value,而key 即是该元素,因此对于之前位数存储换成bit位存储数据能大大的节省存储空间。

    三、BitMap的实现思想

    假设我们要对于0-7内的5个元素(4,7,2,5,3)进行排序(假设元素没有重复),我们可以利用bitmap达到该目的,要表示8个数,我们需要8bit,每个bit相当于一个标志位,我们可以通过标志位(0,1)去标识本次这个元素是否存在(0,标识不存在;1,标识存在,1Byte=8bit)

    首先先开辟1byte的空间,将8个bit位设为0.如这张图 

    0

    0

    0

    0

    0

    0

    0

    0

    然后遍历这几个元素,4为第一个元素,所以把4对应的位置变为1.如下图

    0

    0

    0

    0

    1

    0

    0

    0

    接下去遍历可以得到:

    0

    0

    1

    1

    1

    1

    0

    1

    然后我们通过GETBIT这个命令可以遍历bit区域,将标识为1的遍历出来,得到(2,3,4,5,7)序列,这样子就得到了排序的结果。

    GETBIT key offset

    四、BitMap 40亿数据处理题目

       给你一个文件,里面包含40亿个整数,如何利用bitMap思想找出该文件中不包含的一个整数, 假设你有1GB内存可用。

      我们用1Byte代替一个整数,那40亿数据大概要40*10^8*bit = 0.5GB,满足内存要求。

      用int来表示:Int  bmap[1+sum/32]; //N是总数,sum=40*(10^8),一个int=32Bit=4Byte

      然后我们插入一个整数ze,要先计算整数ze位于数组Bitmap中的索引:index = ze/32;(除以32是得到整数位于第几个Byte,也就是第几位)

      比如整数35,index=35/32=1, 35%32=3(取余) 第35位于数组中的index=1(位于数组BitMap[1]中标识等于3的位置),然后就是标识这个位置为1。

      知道了这些,我们就可以检测哪个整数不在数据里面了。

      如:检测35,先计算index,在数组BitMap的标识位置

      35: index = 1, 在BitMap[1]中的位置为 1,只需要检测这个位置是否为1

      BitMap[1] &(1<<1),这样是1返回true,否侧返回false 

    五、Bit-Map的应用

          1)可进行数据的快速查找,判重,删除,一般来说数据范围是int的10倍以下。

           2)去重数据而达到压缩数据

    BitCount

     

    一、bitcount.语法

    BitCount:计算key 所储存的字符串值中,被设置为 1 的比特位的数量。

    BITCOUNT key

    BITCOUNT key start end

    计算key 所储存的字符串值中,指定字节区间[start,end]被设置为 1 的比特位的数量。
    注意:redis的setbit设置或清除的是bit位置,而bitcount计算的是byte位置,1byte=8bit。
    start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值:比如 -1 表示最后一个字节,而 -2 表示倒数第二个字节,以此类推。

    二、使用bitcount统计浏览数量

    如记录网站上的用户的上线频率,例如计算用户A上线了多少天,用户B上线了多少天,以此作为数据,这可以用SETBIT和BITCOUNT来实现。

    每当用户在某一天上线的时候,通过SETBIT命令,以用户名作为key,将那天所代表的网站的上线日作为offset (标识偏移数)参数,并将这个offset 上的为设置为1。

    举个例子,如果今天是网站上线的第66天,而用户(user=Y)在今天阅览过网站,那么执行命令SETBIT person:Y 66 1;如果88号那天用户(user=Y)也继续阅览网站,那么执行命令SETBIT person:Y 88 1,

    使用BITCOUNT命令:计算用户(user=Y)总共上线次数时

    执行BITCOUNT person:Y,得出用户(person=Y)上线的总天数。

    三、Python-redis-Bitcount 代码

    import redis
    
    r = redis.Redis(host='127.0.0.1', port=6379, db=0)
    
    
    #模拟A用户 ,一年中 每三天登录一次。  
    for i in range(3, 365, 3):
        r.setbit('ua', i, 1)
    
    #模拟B用户,一年中 每60天登录一次。
    for i in range(1, 365, 60):
        r.setbit('ub', i, 1)
    
    userList = r.keys('u*')
    #用户列表
    print userList
    
    #存放活跃用户列表
    Au = []
    #存放非活跃用户列表
    Nau = []
    
    for u in userList :
        # 计算登录次数
        loginCount = r.bitcount(u)
        if loginCount > 100 :
            # 列表添加元组 ()对象
            Au.append((u, loginCount))
        else :
            Nau.append((u, loginCount))
    
    for l in Au :
        print l[0] + ' 是活跃用户. 登陆' + str(l[1]) + ''
    
    for l in Nau :
        print l[0] + ' 是非活跃用户. 登陆' + str(l[1]) + ''
    
    结果:
    ['ub', 'ua']
    ua 是活跃用户. 登陆121天
    ub 是非活跃用户. 登陆7天

    Bittop命令

    处理不同长度的字符串

    当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0 。

    空的 key 也被看作是包含 0 的字符串序列

          

        

     

  • 相关阅读:
    laravel 使用DB 鏈接leftJoin查詢
    checkbox复选框,如何让其勾选时触发一个事件,取消勾选时不触发
    js获取上传图片大小,判断上传图片类型,获取图片真实宽度和高度
    如何查看crontab的日志记录
    linux应用之gcc环境的安装
    laravel 获取上一条insert语句产生的id
    laravel多条件查询(and,or嵌套查询)
    laravel ORM 模型关联 with () 用法
    js实现表单提交 onsubmit
    如何利用jquery来给input添加或删除disabled属性
  • 原文地址:https://www.cnblogs.com/yswyzh/p/9600260.html
Copyright © 2011-2022 走看看