位图算法是一种使用二进制位来表示一个数是否存在的算法。

  •   一个字节是八位二进制,可以表示两种状态,1和0。1表示存在,0表示不存在。

  •   四个字节是32位二进制,可以表示32种状态。

  •   八个字节是64位二进制,可以表示64种状态。

  比如这道题:

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

   这是一道腾讯的编程题,看起来也是难难的。如果你想要把这40亿个数存起来,那得需要多少内存?1024*1024*1024*40=4G多的内存。但是如果用位图的思想来做的话,在这里它也只是要求判断一个数在不在这些数中一个字节可以表示8位,4/8=0.5G的内存就可以表示这40个亿整数。

#pragma once
#include<iostream>
#include<vector>
using namespace std;
class BitMap
{
public:
	size_t Resize(const size_t size);
	void Set(size_t x);
	void Reset(size_t x);
	bool Test(size_t x);
protected:
	vector<size_t> _map;
	size_t _size;
};
#define _CRT_SECURE_NO_WARNINGS 1
#include"Bit_Map.h"
#include"commond1.h"

size_t BitMap::Resize(const size_t size)
{
	size_t newsize = _GetNextPrime(size);
	_map.resize(newsize);
	return newsize;
}
void BitMap::Set(size_t x)
{
	size_t index = x >> 6;//x/32。在顺序表的哪个下标处
	while (_map.size() <=index)
		Resize(_map.size());
	size_t tmp = 1 << (32 - (x % 32));//找到要修改的位
	if (_map[index] & tmp)
	{
		return;
	}
	_map[index] = _map[index] | tmp;
	_size++;
}
void BitMap::Reset(size_t x)
{
	size_t index = x >> 6;//x/32
	size_t tmp = 1 << (32 - (x % 32));
	if (_map[index] | tmp)
	{
		_map[index] = _map[index] & (~tmp);
		_size--;
	}
}
bool BitMap::Test(size_t x)
{
	size_t index = x >> 6;
	if (_map[index] & (1 << (32 - (x % 32))))
		return true;
	else
		return false;
}
commond1.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<assert.h>

//公有的全局函数要放在一个头文件中,不能放在.cpp中,会有重定义链接错误
size_t _GetNextPrime(size_t size)
{
	const int _PrimeSize = 28;
	static const unsigned long _PrimeList[_PrimeSize] =
	{
		53ul, 97ul, 193ul, 389ul, 769ul,
		1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
		49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
		1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
		50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
		1610612741ul, 3221225473ul, 4294967291ul
	};
	for (int i = 0; i < _PrimeSize; ++i)
	{
		if (_PrimeList[i] > size)
			return _PrimeList[i];
	}
	return 4294967291ul;
}

   

wKioL1c0knHxiYabAAAUWxh6ksI603.png

   我们要表示这40个亿的数,我们就开能表示40个亿数的空间。将要找的数通过x除以32(4个字节)来找到它是在第几个size_t内,然后加上它的余数x%32就可以找到它的最终位置。将那个位置置为1就表示这个数存在。