位图算法及其应用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位图算法及其应用相关的知识,希望对你有一定的参考价值。

  • 位图算法

    位图法就是bitmap的缩写,所谓bitmap,是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是用来判断某个数据存不存在的。

技术分享

  • 应用

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

  解决方法申请512M的内存一个bit位代表一个unsigned int值读入40亿个数,设置相应的bit位读入要查询的数,查看相应bit位是否为1,为1表示存在,为0表示不存在。

   2.使用位图法判断整形数组是否存在重复

    解决办法判断集合中存在重复是常见编程任务之一,当集合中数据量比较大时我们通常希望少进行几次扫描,这时双重循环法就不可取了。位图法比较适合于这种情况,它的做法是按照集合中最大元素max创建一个长度为max+1的新数组,然后再次扫描原数组,遇到几就给新数组的第几位置上1,如遇到 5就给新数组的第六个元素置1,这样下次再遇到5想置位时发现新数组的第六个元素已经是1了,这说明这次的数据肯定和以前的数据存在着重复。这种给新数组初始化时置零其后置一的做法类似于位图的处理方法故称位图法。它的运算次数最坏的情况为2N。如果已知数组的最大值即能事先给新数组定长的话效率还能提高一倍。

    3.使用位图法进行整形数组排序

  解决办法

 首先遍历数组,得到数组的最大最小值,然后根据这个最大最小值来缩小bitmap的范围。这里需要注意对于int的负数,都要转化为unsigned int来处理,而且取位的时候,数字要减去最小值。

应用1代码实现:

#pragma once
#include<vector>
template<class T>
struct DataType
{
	long long operator()(const T&key)
	{
		return key;
	}
};
template<class T>
struct StringType
{
	long long operator()(const string&key)
	{
		long long size = 0;
		for (int i = 0; i < key.size(); i++)
		{
			size += key[i];
		}
		return size;
	}
};
template<class T,class BMFunc=DataType<T>>
class BitMap
{
public:
	BitMap(size_t size = 1)
	{
		_a.resize(size / 32 + 1);
	}
	~BitMap(){}
	void set(T &x)
	{
		BMFunc bmf;
		size_t index = bmf(x)/ 32;
		size_t num = bmf(x) % 32;
		if (!(_a[index] & (1 << num)))
		{
			_a[index] |= (1 << num);
			_size++;
		}
		
	}
	void Reset(T x)
	{
		BMFunc bmf;
		size_t index = bmf(x) / 32;
		size_t num = bmf(x) % 32;
		if (!(_a[index] & (1 << num)))
		{
			_a[index] &= (~(1 << num));
			_size--;
		}
	}
	bool Test(T x)
	{
		BMFunc bmf;
		size_t index = bmf(x)/ 32;
		size_t num = bmf(x)% 32;
		return _a[index] &(1 << num);
	}
protected:
	vector<size_t> _a; 
	size_t _size;
};

应用2代码实现:

bool hasDuplicatedItem(int *a, int len)
{
	int length, max, i;
	length = len;
	max = a[0];
	for (i = 1; i < length; i++){
		if (a[i] > max)
			max = a[i];
	}
	int *arr;
	arr = (int*)malloc(sizeof(int)* (max + 1));
	for (i = 0; i < length; i++){
		if (arr[a[i]])
			return true;
		else
			arr[a[i]] = 1;
	}
	return false;
}

应用3代码实现:

void bitmapSort(int *a, int len)
{
	int length, max, min, i, index;
	length = len;
	min = max = a[0];
	//找出数组最大值
	for (i = 1; i < length; i++){
		if (a[i] > max){
			max = a[i];
		}
		if (min > a[i]) {
			min = a[i];
		}
	}
	//得到位图数组
	int *arr;
	arr = (int*)malloc(sizeof(int)* (max - min + 1));
	for (i = 0; i < length; i++){
		index = a[i] - min;
		arr[index]++;
	}
	//重整a中的元素
	int arr_length;
	arr_length = max - min + 1;
	index = 0;
	for (i = 0; i < arr_length; i++){
		while (arr[i] > 0){
			a[index] = i + min;
			index++;
			arr[i]--;
		}
	}
}




本文出自 “学习记录” 博客,转载请与作者联系!

以上是关于位图算法及其应用的主要内容,如果未能解决你的问题,请参考以下文章

将位图从片段保存到内部/外部存储[关闭]

哈希及其原理

数据结构之位图

合并两个位图的问题

delphi GDI 图片压缩代码 据说是位图缩放保持原图视觉效果最好的算法

机器学习中分类算法及其在乳腺癌中的预测应用代码