Bitmap的巧用

打印 上一主题 下一主题

主题 555|帖子 555|积分 1665

题目

关于用户标签的需求:用户标签包括用户的社会属性、生活习惯、消费行为等信息。例如,步伐员,有驾照,单身等等。通过用户标签,可以对多样的用户群体进行统计。例如,统计用户的男女比例,统计喜欢旅游的用户数量等。
通常的思路,是使用关系型数据库,好比Occupation表现用户职位,gender表现性别等等。表的一行记录,为一个用户的标签。但是假如有很多标签的话,则需要给表加很多列,不好维护。
思路

Bitmap算法,在中文里又叫作位图算法。位图,是指内存中连续的二进制位(bit),所组成的数据布局,该算法主要用于大量整数做去重和查询操作。
举例,有100bit的Bitmap,每一个bit位都表现着,从0到99的整型数。假如想用bit位,表现某些数字,只需将对应位的bit设置位1即可。例如,向100bit的Bitmap中,生存55,77,88,只需要将对应位设置为1即可。
这样,就可以用Bitmap和用户表里的id建立映射关系,假如一个步伐员标签,有一个用户的id位99,只需要将表现步伐员标签的Bitmap的第99位,设置为1,就表现id为99的用户职位是步伐员。
还可以,进行与,或,异或等逻辑运算。
假设,有两个10bit的Bitmap,一个表现是男性的标签{0,0,0,0,0,0,1,1,1,0},一个表现是00后的标签{0,0,0,0,0,0,0,0,1,0},求这10bit的Bitmap中,即是男性,也是00后的用户,进行逻辑&运算即可,或就进行|元素。非00后,就需要代表00后的标签和,全部的用户的Bitmap,进行异或运算,就是说,在全部用户的Bitmap中过滤掉是00后的即可。
代码
  1. public class MyBitmap {
  2.     //每一个word是一个long类型元素,对应一个64位二进制
  3.     private long[] words;
  4.     //Bitmap的总位数大小
  5.     private int size;
  6.     public MyBitmap(int size){
  7.         this.size = size;
  8.         this.words = new long[(getWordIndex(size - 1) + 1)];
  9.     }
  10.     /**
  11.      * 获取Bitmap某一位的状态
  12.      * @param bitIndex 位图的第bitIndex位
  13.      */
  14.     public boolean getBit(int bitIndex){
  15.         if(bitIndex < 0 || bitIndex > size - 1)
  16.             throw new IndexOutOfBoundsException("超过Bitmap有效范围");
  17.         int wordIndex = getWordIndex(bitIndex);
  18.         return (words[wordIndex] & (1L << bitIndex)) != 0;
  19.     }
  20.     /**
  21.      * 把Bitmap某一位设置为true
  22.      */
  23.     public void setBit(int bitIndex){
  24.         if(bitIndex < 0 || bitIndex > size - 1)
  25.             throw new IndexOutOfBoundsException("超过Bitmap有效范围");
  26.         int wordIndex = getWordIndex(bitIndex);
  27.         words[wordIndex] |= (1L << bitIndex);
  28.     }
  29.     /**
  30.      * 获取某一个Bitmap对应的word
  31.      * @param bitIndex 位图的第bitIndex位
  32.      */
  33.     private int getWordIndex(int bitIndex){
  34.         return bitIndex >> 6;// bitIndex / 64
  35.     }
  36.     public static void main(String[] args) {
  37.         MyBitmap myBitmap = new MyBitmap(128);
  38.         myBitmap.setBit(126);
  39.         myBitmap.setBit(75);
  40.         System.out.println(myBitmap.getBit(126));
  41.         System.out.println(myBitmap.getBit(78));
  42.     }
  43. }
复制代码
只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

星球的眼睛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表