摘要
该算法常用到包分类中,初次接触到bit vector算法是在对海量数据的处理。
设想我们有个很大的数据集,它的总体个数为400亿个数字,需要消除重复的数据,一种想当然的做法是,每次读取一部分,进行消重,如每次读取1000万个数据进行消重,这样我们就可以将40亿个数字分成400部分,将消重后的数据合并,然后进行进一步消重,这种做法显然需要的花费很大的时间开销。假设将所有数据都读取到内存中,发现至少需要几个G的内存才嫩容纳这么多数据。

Bit Vector解决方案
我们构造一个位数组,在java中实际上是由byte数组实现的,在c中我们可以使用char数组代替。设bit vector的第一位对应数字1,第二位对应数字2,那么第N位对应数字N,当我们读入一个数据的时候,将对应位置为1。这样就能将所有的数据都读入到一个bit vector中,显然这种方案也有缺点,设想我们如果读入2个数据,一个是1,一个是1000000,那么bit vector的长度取决于最大数,所以,bit vector适用在数据长度均衡的情况下。
Bit Vector实现:

图1

如图1所示,假设i的1,那么i肯定映射在第一个byte中,若i是15,那么它将映射在第3个byte中,对于任意数据i,它将映射到下标为i/8向下取整再加1的byte数组中。
Bit vector实现函数:
Set(置位):对于读入的数据,将对应的bit位置为1。
Clear(清楚位):对于删除的数据,将对应的bit位置为0。
Get(读取位):读取某一位数据,结果是1则证明存在,为0则证明不存在。
Size(bit vector所能容纳的位个数):返回容器的长度。
Count(置位元素个数):返回所有被置为1的位的个数。

C代码实现(原文中没有提供C实现,以下为自己实现的代码)

typedef struct{u8 * bits;    //这里采用char代替java中的byte,考虑到兼容性,这里采用u8int size;int count;
}BitVector;//初始化BitVector
void init(BitVector * bv,int size){bv->size = size;bv->bits = (u8 *)calloc(sizeof(u8),size>>3 + 1);bv->count = 0;
}void set(BitVector *bv,int data){if(bv->bits[data>>3] & 1<<(data&7) == 0){//由于下标从0开始,所以无需data>>3+1bv->bits[data>>3] |= 1<<(data&7); //bit&7相当于截取后3位,等价于对8取余bv->count ++;        }
}void clear(BitVector * bv,int data){if(bv->bits[data>>3] & 1<<(data&7) == 1<<(data&7)){bv->bits[data>>3] &= ~(1<<(data&7)); bv->count --;}
}//返回1表示存在于bv,否则不存在于bv
int get(BitVector * bv,int data){return (bv->bits[data>>3] & 1<<(data&7));
}int getCount(BitVector * bv){return bv->count;
}

原文java实现

private byte[] bits;
private int size;
private int count = -1;
public BitVector(int n) {size = n;bits = new byte[(size >> 3) + 1];
}public final void set(int bit) {bits[bit >> 3] |= 1 << (bit & 7);count = -1;
}
public final void clear(int bit) {bits[bit >> 3] &= ~(1 << (bit & 7));count = -1;
}
public final boolean get(int bit) {return (bits[bit >> 3] & (1 << (bit & 7))) != 0;
}
/**
* 原文中没有在set和clear的时候进行count统计,所以它实现了一个getCount()函数
* 具体做法是遍历byte数组,由于每个byte数组中的1的取值可能只有0-255种,所以就
* 计算出byte数组中每个byte中1的个数,之后通过循环将整个byte数组的1的个数相
* 加即可。采用的是少量空间换时间的方案。对于每一种byte可能的取值的1的个数都进
* 行统计。在获取count不频繁的情况下,这种做法较为科学。
*/
private static final byte[] BYTE_COUNTS = {   // table of bits/byte0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};public final int count() {if (count == -1) {int c = 0;int end = bits.length;for (int i = 0; i < end; i++)c += BYTE_COUNTS[bits[i] & 0xFF];   // sum bits per bytecount = c;}return count;
}

原文地址:https://www.jianshu.com/p/2dbb88e2bfa9

Bit Vector算法相关推荐

  1. STL(标准模板库)—Vector

    目录 Vector 1.创建一个名为V的vector容器 整型数组 2.vector容器中存放自定义的数据类型 3.vector容器嵌套容器 Vector遍历打印函数 vector容器_构造函数 1. ...

  2. STL容器板子(vector篇)

    一.STL的诞生 (1)长久以来,软件界一直希望建立一种可重复利用的东西 (2)C++的面向对象和泛型编程思想,日的就是复用性的提升 (3)大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量 ...

  3. C++学习笔记(十五)vector及string

    STL初始 1.STL的诞生 //长久以来,软件界一直希望建立一种可重复利用的东西 //C++的面向对象和泛型编程思想,目的就是复用性的提升 //大多情况下,数据结构和算法都未能有一套标准,导致被迫从 ...

  4. C++《STL全集》

    STL初识 STL的诞生 长久以来,软件界一直希望建立一种可重复利用的东西 C++的面向对象和泛型编程思想,目的就是复用性的提升 大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作 ...

  5. 黑马程序员学习笔记-------c++提高编程

    c++提高编程 本阶段主要针对c++泛型编程和STL技术做详细讲解,探讨cpp更深层的使用 1 模板 1.1 模板的概念 模板就是建立通用的模具,大大提高复用性 模板的特点: 模板不可以直接使用,它只 ...

  6. C++学习系列(三)—— 泛型编程(STL)

    原文链接:https://www.wkeyu.cn/235.html C++提高编程 本阶段主要针对C++泛型编程 和***STL*** 技术做详细学习,学习C++更深层次的使用 代码仓库:https ...

  7. 基础语法值c++提高编程

    c++的提高编程 本阶段主要针对c++泛型编程和STL技术作详细讲解,探讨c++更深层的使用 1.模板 1.1模板的概念 模板就是建立通用模具,大大提高复用性. 例如生活中的存照模板,ppt模板 模板 ...

  8. 【C++自学笔记 提高编程篇(二)STL初识】

    STL初识 2 STL初识 2.1 STL的诞生 2.2 STL基本概念 2.3 STL六大组件 2.4 STL中容器.算法.迭代器 2.5容器算法迭代器初识 2.5.1 vector存放内置数据类型 ...

  9. A005 C++提高编程

    C++提高编程 1 模板 1.1 模板的概念 1.2 函数模板 1.2.1 函数模板语法 1.2.2 函数模板注意事项 1.2.3 函数模板案例 1.2.4 普通函数与函数模板的区别 1.2.5 普通 ...

最新文章

  1. Git学习笔记07-删除文件
  2. mysql修行练级之字符集,数据类型与存储引擎选择
  3. Draw Circle 沿着圆运动~~
  4. 并发编程基础之volatile关键字的用法
  5. vs2008环境下MFC对注册表的读写操作
  6. IOS之代理的使用(重点)
  7. word-vba-microsoft(中英文)
  8. mui 头部tab代码2
  9. 你如何在PowerShell中注释掉代码?
  10. 开课吧python小课学了有用吗-好消息!今天,审计、会计、税务、财务主管彻底沸腾了……...
  11. [转载] 深层复制构造函数和浅层复制构造函数区别
  12. [Contest20180328]coin
  13. Java_脚本引擎_01_用法入门
  14. 信号完整性(SI)电源完整性(PI)学习笔记(三十三)102条使信号完整性问题最小化的通用设计规则
  15. 数字孪生技术下的智慧医院再添新功能,室内地图导航让你“医”路畅通
  16. openlayers 仿CAD(1)
  17. 如何缩小图片大小(手机照片怎么缩小尺寸)
  18. 径向基网络(RBF network)之BP监督训练
  19. linux开组态软件,基于嵌入式Linux的组态软件实时数据库的设计
  20. 儿童智能手表APP开发具备哪些功能

热门文章

  1. css中按钮变色,CSS控制按钮变色(有图有真相)
  2. vue实现生成二维码,并生成图片
  3. 如何将电脑文件同步备份到u盘或移动硬盘?
  4. 8位二进制数中,对于-128的一些个人理解
  5. PTA乙级 1086 就不告诉你——15分
  6. HTML人物介绍、个人设计web前端大作业、贝聿铭人物介绍(带报告3000字)
  7. 只要掌握这两个方法便可快速学会怎么剪裁视频尺寸
  8. c语言上期中考试试卷答案,2007~2008学年度上学期C语言程序设计期中试卷及答案...
  9. 请这样爱你的移动硬盘
  10. python的时间转换datetime和pd.to_datetime