什么是位图?

在这里插入图片描述

目录:

一.位图

引入

面试题【腾讯】 : 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。

可能我们大多数人了解到的位图都是看到了腾讯的这个面试题理解到的,下面我就读于位图进行详细的讲解.

1.位图概念

在这里插入图片描述

位图就是一种直接定址的哈希,它的效率很高,只用O(1)就可以查到对应位置是0还是1

2.位图的实现原理

(1)构建方式

在这里插入图片描述

(2)存储方式

在这里插入图片描述

3.代码实现

代码的实现还是比较简单的,主要的就是上面对于每个元素存储的具体流程的熟悉.

class BitSet{

public:

	//位图的内存大小和数据范围有关系
	BitSet(size_t range)
		:_bit(range / 8 + 1)
	{}

	//存储
	void set(size_t num)
	{
		//0.计算整数位置
		int idx = num / 8;
		//1.计算比特位位置
		int bitIdx = num % 8;
		//2.对应的比特位变为1
		//按位进行或运算

		_bit[idx] |= 1 << bitIdx;
	}

	//查找
	bool test(size_t num){
	
		int idx = num / 32;
		int bitIdx = num % 32;
		return (_bit[idx] >> bitIdx) & 1;
	}
	//删除
	void reset(size_t num){
		
		int idx = num / 32;
		int bitIdx = num % 32;
		_bit[idx] &= ~(1 << bitIdx);
	}

private:
	vector<int> _bit;
};

4.应用场景

它就是主要应用于对于比较大的数据的标记存储,能大量的节省空间,而且对应的时间复杂度只有O(1),方便查找.就像上面的面试题,我们完全可以将数据全部标记在对应的位图中,然后查找对应的数据位置,看其位置是否是1,就能轻松地解决这个问题.

二.布隆过滤器

在这里插入图片描述

布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可能存在,因为有些哈希函数存在一定的误判。

1.优点

  1. 增加和查询元素的时间复杂度为:O(K), (K为哈希函数的个数,一般比较小),与数据量大小无关
  2. 哈希函数相互之间没有关系,方便硬件并行运算
  3. 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势
  4. 在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势
  5. 数据量很大时,布隆过滤器可以表示全集,其他数据结构不能
  6. 使用同一组散列函数的布隆过滤器可以进行交、并、差运算

2.缺点

  1. 有误判率,即存在假阳性(False Position),即不能准确判断元素是否在集合中(补救方法:再建立一个白名单,存储可能会误判的数据)
  2. 不能获取元素本身
  3. 一般情况下不能从布隆过滤器中删除元素
  4. 如果采用计数方式删除,可能会存在计数回绕问题
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
位图是一种用于表示图像的数据结构,其中每个像素用二进制位表示。在C++中,位图通常被表示为一个二维数组,其中每个元素都是一个二进制位。位图通常用于图像处理和计算机图形学中。 位图可以使用各种方法进行操作,包括读取、写入和修改像素值。以下是一些常见的位图操作: 1. 读取位图:使用文件输入流读取位图文件,并将其解析为二维数组。 2. 写入位图:使用文件输出流将位图数据写入文件中。 3. 修改像素值:可以通过修改位图数组中的特定元素来更改像素值。 4. 显示位图:将位图数据转换为图像并将其显示在屏幕上。 5. 图像处理:可以对位图进行各种处理,如图像缩放、旋转、裁剪等。 下面是一个简单的示例代码,展示如何使用C++读取位图文件并显示其内容: ```c++ #include <iostream> #include <fstream> #include <string> using namespace std; int main() { // 打开文件 ifstream file("image.bmp", ios::binary); // 读取文件头 char header[54]; file.read(header, 54); // 读取图像数据 int width = *(int*)&header[18]; int height = *(int*)&header[22]; int padding = 0; while ((width * 3 + padding) % 4 != 0) { padding++; } int size = width * height * 3 + height * padding; char* data = new char[size]; file.read(data, size); // 显示图像 for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int index = (y * width + x) * 3; char r = data[index + 2]; char g = data[index + 1]; char b = data[index]; cout << "(" << (int)r << ", " << (int)g << ", " << (int)b << ") "; } cout << endl; } // 关闭文件 file.close(); return 0; } ``` 该示例代码使用了C++的文件读写功能和动态内存分配来读取位图文件并显示其内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值