数据结构之位图
来源:互联网 发布:urlencoder函数php 编辑:程序博客网 时间:2024/05/27 00:32
前言
因为之前上数据挖掘的课的老师经常在课上提到这种方法,正好我又不会,于是抽点时间出来写一篇Blog学习一下这种数据结构。
问题导入
给定40亿个不重复的unsigned int的整数,没有排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中。
快速思考
C语言总一个int变量占32位,即4个字节,那么如果用一个40亿的数组来存储的话,需要的空间就是40亿x4Bytes = 160亿 Bytes = 14G,显然计算机的内存这样就爆了。所以就引出了位图的方法。
定义
实际上一个int有32位,而我仅仅拿来存储了32个数,如果我每一位都拿来存储一个数呢?比如一个int型变量,我要存储数15,那么就将第15位上置为1,我要存储20,就把第20位上置为1,以此类推,这样我一个int型变量就能存储32个数。
所申请的int数组如下:
如何确定某一个数A在哪个位置呢?
首先要得到其在那个字节,即A / 32.
其次要得到在哪一位,即 A % 32
采用位运算可以更快的进行计算。
A/32 = A >> 5(向右移动5次)
A%32 = A & (0x1F)
解决
因此上述的问题就可以只用40亿个bit = 1.25亿个Bytes来解决,显然对内存的要求要低许多。思路就是读取40亿个整数,对于每一个数将某一bit置1,然后对于陌生的数,直接判断其对应的位是1还是0即可。
代码
#define MAX 4000000000#define MASK 0x1F#define DIGITS 32int a[MAX/DIGITS];void set(int num) {//将某数的逻辑位置置1 a[num>>5] |= (1 << (n&MASK)); //num>>5相当于求字节位置,num&MASK相当于求位位置} void clear(int num) {//将某数的逻辑位置清0 a[num>>5] &= (~(1<<(n&MASK)));}void test(int num) { return a[num>>5] & (1<<(n&MASK));}
C++ STL bitmap头文件中提供了bitmap的实现
http://www.cplusplus.com/reference/bitset/bitset/
#include <iostream>#include<bitset> using namespace std;int main(int argc, char *argv[]){ const int max = 10000000; int n,i; bitset<max+1> bit; //初始默认所有二进制位为0 while(scanf("%d",&n)!=EOF) { bit.set(n,1); //将第n位置1 } for(i=0;i<=max+1;i++) { if(bit[i]==1) printf("%d ",i); } return 0;}
其余应用
1.排序
先将数组中所有的数读进去,然后从低位到高位遍历一遍,即可得到升序的结果。
2.两个数组求交集
用两个位图,然后对两个位图进行与操作,即可得到这两个数组的交集。
等等!
- 数据结构之位图(11)
- 数据结构之位图
- 数据结构之位图
- 数据结构之位图
- 位图数据结构
- 位图数据结构
- 【数据结构】位图
- 【数据结构】位图
- 数据结构--位图
- 数据结构:位图
- 位图之屏蔽位图
- FOJ 1001之位图数据结构对程序的优化
- c/c++ 数据结构之位图(bitmap)详解
- 数据结构之位图(bitmap)详解 (转)
- matlab实现位图数据结构
- 位图数据结构的运用
- 位图文件的数据结构
- 数据结构:位图法
- 纸上得来终觉浅,绝知此事要躬行 javadec
- BZOJ 4689 Find the Outlier 高斯消元
- 一中OJ #3514 礼物 | 暴搜 + 剪枝 | 解题报告
- 初识 Spring Boot
- GitHub提交项目
- 数据结构之位图
- Android ANR产生的原因及定位分析
- 17/10/23 题目泛做
- tyvj P4620 一方的loli量产计画 (快速幂)
- 利用二维图像进行头部姿态估计
- bin/mysqld: error while loading shared libraries: libnuma.so.1: 安装mysql
- 我的第一篇博客
- 深度学习笔记6:全连接层的实现
- html checkbox多选复选框form控件元素