位图的概念
位图是一种图像存储方式,也称为二维位数组。它将图像中的每个像素点都表示为一个二进制位。位图可以包含黑白像素或彩色像素,每个像素的颜色信息都用二进制数据来表示。
在位图中,每个像素都有一个对应的二进制数值,通常是用几个字节来表示,表示的数值范围决定了颜色的种类和精度。例如,对于黑白图像,每个像素只需要1位来表示,0代表黑色,1代表白色;对于彩色图像,常见的有24位颜色深度,每个像素用3个字节来表示,分别代表红、绿、蓝三个通道的亮度。位图的宽度和高度决定了图像的大小。
位图的应用
位图思想和哈希思想类似,将数据进行映射,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。
如图题。数据量特别大,我们就可以运用位图:数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在
可以创建一个整形数组。
代码实现:
template<size_t N>
class bitset
{
public:
bitset()
{
_bit.resize(N/32+1,0);
}
void set(size_t x)
{
assert(x <= N);
size_t i = x / 32;
size_t j = x % 32;
_bit[i] |= (1 << j);
}
bool test(size_t x)
{
assert(x <= N);
size_t i = x / 32;
size_t j = x % 32;
return _bit[i] & (1 << j);
}
private:
vector<int> _bit;
};
布隆过滤器
布隆过滤器使用一个很长的二进制向量和一组哈希函数来表示一个集合。当一个元素被加入集合时,通过哈希函数将元素映射到二进制向量上的几个位置,将这些位置标记为1。使用哈希函数的随机性,可以使得多个元素映射到同一个位置的概率很低。
当需要判断一个元素是否在集合中时,同样使用哈希函数将元素映射到二进制向量上的位置,然后检查这些位置是否都为1。如果都为1,表示该元素可能在集合中;如果有一个位置为0,那么该元素一定不在集合中。
布隆过滤器的应用
将大量将要进行映射的数据,通过两种或多种哈希函数进行算值,映射在一个数组中。
如下图下x,y经过Hash函数取模之后分别对应了两个位置进行映射,这样可以大大降低数据冲突情况!(x,y可以是任意数据,字符串,整形等等)
代码实现:
struct HashFuncBKDR
{
// BKDR
size_t operator()(const string& s)
{
size_t hash = 0;
for (auto ch : s)
{
hash *= 131;
hash += ch;
}
return hash;
}
};
struct HashFuncAP
{
// AP
size_t operator()(const string& s)
{
size_t hash = 0;
for (size_t i = 0; i < s.size(); i++)
{
if ((i & 1) == 0) // 偶数位字符
{
hash ^= ((hash << 7) ^ (s[i]) ^ (hash >> 3));
}
else // 奇数位字符
{
hash ^= (~((hash << 11) ^ (s[i]) ^ (hash >> 5)));
}
}
return hash;
}
};
struct HashFuncDJB
{
// DJB
size_t operator()(const string& s)
{
size_t hash = 5381;
for (auto ch : s)
{
hash = hash * 33 ^ ch;
}
return hash;
}
};
template<size_t N, class K = string, class Hash1 = HashFuncBKDR, class Hash2 = HashFuncAP, class Hash3 = HashFuncDJB>
class Bloom
{
public:
void Set(const K& s)
{
size_t hash1 = Hash1()(s) % M;
size_t hash2 = Hash2()(s) % M;
size_t hash3 = Hash3()(s) % M;
_bl->set(hash1);
_bl->set(hash2);
_bl->set(hash3);
}
bool Test(const K& s)
{
size_t hash1 = Hash1()(s) % M;
if (_bl->test(hash1) == false)
return false;
size_t hash2 = Hash2()(s) % M;
if (_bl->test(hash2) == false)
return false;
size_t hash3 = Hash3()(s) % M;
if (_bl->test(hash3) == false)
return false;
return true;
}
private:
static const size_t M = 10 * N;
std::bitset<M>* _bl = new std::bitset<M>;
};