题目
关于用户标签的需求:用户标签包括用户的社会属性、生活习惯、消费行为等信息。例如,步伐员,有驾照,单身等等。通过用户标签,可以对多样的用户群体进行统计。例如,统计用户的男女比例,统计喜欢旅游的用户数量等。
通常的思路,是使用关系型数据库,好比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后的即可。
代码
- public class MyBitmap {
- //每一个word是一个long类型元素,对应一个64位二进制
- private long[] words;
- //Bitmap的总位数大小
- private int size;
- public MyBitmap(int size){
- this.size = size;
- this.words = new long[(getWordIndex(size - 1) + 1)];
- }
- /**
- * 获取Bitmap某一位的状态
- * @param bitIndex 位图的第bitIndex位
- */
- public boolean getBit(int bitIndex){
- if(bitIndex < 0 || bitIndex > size - 1)
- throw new IndexOutOfBoundsException("超过Bitmap有效范围");
- int wordIndex = getWordIndex(bitIndex);
- return (words[wordIndex] & (1L << bitIndex)) != 0;
- }
- /**
- * 把Bitmap某一位设置为true
- */
- public void setBit(int bitIndex){
- if(bitIndex < 0 || bitIndex > size - 1)
- throw new IndexOutOfBoundsException("超过Bitmap有效范围");
- int wordIndex = getWordIndex(bitIndex);
- words[wordIndex] |= (1L << bitIndex);
- }
- /**
- * 获取某一个Bitmap对应的word
- * @param bitIndex 位图的第bitIndex位
- */
- private int getWordIndex(int bitIndex){
- return bitIndex >> 6;// bitIndex / 64
- }
- public static void main(String[] args) {
- MyBitmap myBitmap = new MyBitmap(128);
- myBitmap.setBit(126);
- myBitmap.setBit(75);
- System.out.println(myBitmap.getBit(126));
- System.out.println(myBitmap.getBit(78));
- }
- }
复制代码 只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |