Java教程

bitset和bitmap转载

本文主要是介绍bitset和bitmap转载,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

今天看到大数据处理的BitMap算法,可以有效地对空间进行压缩。

一、BitMap基本思想
在32位的机器上,一个int需要占据32位,而有时候这就是很大的空间浪费。比如没有重复数字的计数排序的时候,假设数据范围[0,1e8],则需要开辟数组int a[(int)1e8+1],a[i]表示i的出现的次数。这就需要大约400M的空间了。然而,由于数字不会重复,所以a[i]只会是0或1,那么32位的int必然对空间造成了很大的浪费。如果是以前,我会改成bool数组,空间下降为100M,然而接触BitMap算法后,我发现bool实际上是个不合理的存在——它用着1byte即8位的空间,却干着1位的事情(非0即1)。因为非0即1,所以完全可以用1位来表示一个数存在或者不存在,空间变为最初的1/32。用一位来表示一个数,这就是BitMap的基本思想

二、BitMap的基本实现
现在可以重新开一个数组int b[(int)1e8/32+1],b[]是a[]的1/32,但需要表达的内容却要和a[]一样多,那么则需要对b[]进行处理。因为一位表示一个数,那么对于任意b[i],自然都是表示32位数了。即:b[0]表示031,b[1]表示3263,以此类推。现在给一个数399,怎么存到b[]数组里呢?首先判断它应该存到b[i]对应的哪个i,这简单,显然i=399/32,也就是i=12。那么再考虑399对应b[12]的哪一位,这也很显然,对应的自然是399%32=15位里。然后问题是怎么将b[12]的第15位变成1?我使用的方法是

b[12] |= (1<<15)。这很好理解~

代码:

const int maxn = 1e8/32 + 1;
int b[maxn];
inline void insert(const int& x)
{
int i = x/32, j = x%32;
b[i] |= (1<<j);
}
三、STL之bitset
我觉得bitset就是bitmap算法在C++里面被封装起来了,也是用位来表示一个数,bitset支持与(unsigned)(long long) int、bool、string之间的相互转化。

头文件:

#include
声明bitset变量:

bitset name
像上面那个数组直接就可以写成:

const int size = 1e8 + 1;
bitset c(0);
这样开辟出来的bitset变量c和上面包含了(1e8/32+1)个int的b数组所占空间差不多。需要注意的是,这里的c是一个占据空间size bit的变量,而不是一个数组,所以后面括号里面的初始值是转化为size长度二进制后赋给c的所有位。额,好像说起来有点抽象,举个栗子:

由这个栗子可以知道bitset支持cout,那么我们可以猜到,bitset同样支持cin,需要注意的是输入必须是01串,否则从第一个非0/1的数字开始就不会读入了。

上面我们自己实现的bitmap插入一个数用insert(x),对于bitset却是可以直接用:

b[x] = 1
没错,bitset可以直接对某一位赋值,这里就有点像string了。不同的是bitset还可以进行&、|、~、^、<<、>>等位运算符。

接下来介绍一下bitset的一些方法:

c.size() // 返回大小(位数)
c.count() // 返回1的个数
c.any() // 返回是否有1
c.none() // 返回是否没有1
c.set() // 全都变成1
c.set§ // 将第p + 1位变成1
c.set(p, x) // 将第p + 1位变成x
c.reset() // 全都变成0
c.reset§ // 将第p + 1位变成0
c.flip() // 全都取反
c.flip§ // 将第p + 1位取反
c.to_ulong() // 返回它转换为unsigned long的结果,如果超出范围则报错
c.to_ullong() // 返回它转换为unsigned long long的结果,如果超出范围则报错
c.to_string() // 返回它转换为string的结果
 
————————————————
版权声明:本文为CSDN博主「SuperAFeiDa」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Q1410136042/article/details/82119599

这篇关于bitset和bitmap转载的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!