位图基本操作与实现

位图

 一、位图的原理在位图中采用比特位表示对应的元素存在或者不存在0:不存在 1:存在,例如一个int整数有32个比特位可以                                         表示0-31个整数。         

 二、位图的优点:使用位图最大的优点就是节省空间。

         位图的缺点:①可读性差   ②存储元素的个数比一般元素要多,但是存储元素的大小受空间大小的限制

位图的实现

位图主要的基本操作:

  • 设置某一位有效(这里默认有效的含义是将对应比特位置为1)
  • 设置某一位无效(这里默认有效的含义是将对应比特位置为0)

请看代码:

//BitMap.h
#pragma once
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Windows.h>
typedef struct BitMap
{
	int* _pBit;
	int _capacity;
	int size;   //比特位为1的个数
}BitMap;

void InitBitMap(BitMap* bm, int totalbit);  //初始化
void SetBitMap(BitMap* bm, int which);   //置1
void UnSetBitMap(BitMap* bm, int which);  //置0

//BitMap.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "BitMap.h"
void InitBitMap(BitMap* bm,int totalbit)
{
	int capacity = 0;
	assert(bm);
	capacity = (totalbit / 32) + 1;    ////一个int可以表示32个元素,totalbit个元素需要size/32 + 1个int来存储
        //注意+1因为1/32 = 0,但是我们需要一个int
	bm->_pBit = (int*)malloc(capacity);
	if (NULL == bm->_pBit)
	{
		assert(0);
		return;
	}
	memset(bm->_pBit, 0, sizeof(int)*capacity);
	bm->_capacity = capacity;
	bm->size = 0;
}
void SetBitMap(BitMap* bm, int which)     //bit位   置1
{
	int index = 0;
    int pos = 0;
	assert(bm);
	index = (which / 32);   //所在的哪个整形空间(32bit位)
	pos = (which % 32);     //所在该整形空间的哪个比特位
	bm->_pBit[index] |= (1 << pos);  //置1
	printf("%d\n", bm->_pBit[index]);
}
void UnSetBitMap(BitMap* bm, int which) // bit位   置0
{
	int index = 0;
	int pos = 0;
	assert(bm);
	index = (which / 32);
	pos = (which % 32);
	bm->_pBit[index] &= ~(1 << pos);
	printf("%d\n", bm->_pBit[index]);
}

//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "BitMap.h"
void test()
{
	BitMap bm;
	InitBitMap(&bm, 10);
	SetBitMap(&bm, 4);
	UnSetBitMap(&bm, 4);
}
int main()
{
	test();
	system("pause");
	return 0;
}

            

位图的应用

  • 1)给定100亿个整数,设计算法找到只出现一次的整数。
          100亿个整数采用位图存储的话需要1.5G的内存,并且如果需要记录出现次数的话一个比特位 
    是无法做到的,我们需要2个比特位那么就需要2.5G的内存,如果我们系统的内存不足够的话, 
    我们需要将100亿个数据分成1000份文件,将每个文件的数据通过位图存储,我们采用两个比特位 
    00:没有出现,01,出现一次,10出现多次,11舍弃,再将这1000个文件中出现一次的数据, 
    统计到一个文件里 
  • 2)给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集。
          将第一个文件的数据分成1000份存储到位图里,再判断第二份文件中的数据是否在位图中。 
  • 3)1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数。
          我们需要将100亿个数据分成1000份文件,将每个文件的数据通过位图存储,我们采用两个比特位 
    00:没有出现,01,出现一次,10出现2次,11舍弃,再将这1000个文件中出现不超过两次次的数据

猜你喜欢

转载自blog.csdn.net/ENSHADOWER/article/details/82746161