BitMap的使用

     BitMap也就是我们所说的位图算法,最常用的就是用来压缩数据。

  前奏 :     

    举个例子:你如果使用int类型的数据来标识数字,则每一个数字需要的4个字节才可以标识,而如果你使用bit的话你只需要一位这样数据的压缩量就是 1/32.

    比如你通常表示的数字1在计算机中的存储为(当然也可以有小端存储)00000000 | 00000000 | 00000000 | 000000001 , 

而如果你使用位图的概念 只需要对应的每一位的有无来表示一个数字这样 1的32个bit位就可以表示 数字 0-31;

    比如一组数:1 3 5 8 9;

    我们从小位开始方便书写:

    0  1  0  1  0  1  0  0  1 ||   1  0  0  0  0  0  0  0 ||  0  0  0  0  0  0  0  0 ||  0  0  0  0  0  0  0  0||

    0  1  2  3  4  5  6  7  8      9 10 11 12 13 14 。。。。。。。。。。。。。。

    我们可以看到对应的 1 3 5 8 9 相应的位置都置为1表示该数字的存在,很简单吧!

    接下来就需要考虑如何才可以把一个数字塞到一个位图中, 如何查询位图是否存在这个数,第三如何删除这个在位图中的数;

    我们先有两个基本的操作: 

    index(num)  //获取num在位图的中段落,

    对应的如果位图选择的是每32位一段则: index(num) = num/32, 也就是你的位图是用int类型来存储;

    如果为8位为一段则: index(num) = num/8;

    position(num) //获得在该段中的具体位置,同理:

    position(num) = num%8;    // num & 0x07;

    position(num) = num%32;  // num & 0x1F; 

    各段代码:

``

    下面贴具体操作的实际代码:(主要看add , clear ,与contain三个函数)

     BitMap.cpp

 #include"BitMap.h"
 #include<iostream>
 #include<memory.h>
/**
// author:L
// date: 2018.4.8
// 尚未解决重复输出的问题,可以在适当的位置插上key但违反了最初数据压缩的意思;
**/
BitMap::BitMap():alloc_size_ (100),max_len_(0){
  byte_ = new char[alloc_size_];
  for(int i=0; i<alloc_size_; i++){
    byte_[i] &= 0;
  }
  //memset(byte_,NULL,sizeof(char)*alloc_size_);
}
//目前所写的size实际上是根据最大的数申请的;
BitMap::BitMap(int size):alloc_size_(size),max_len_(0){
  byte_ = new char[alloc_size_]; //失败的时候回触发std::alloc
  //可以捕获异常么;
  //memset(byte_,0,sizeof(char)*alloc_size_);
  for(int i=0; i<alloc_size_; i++){
    byte_[i] &= 0;
  }
}


BitMap::~BitMap(){
  delete [] byte_;
}
//并未考虑无法插入的问题;
void BitMap::add(int num){
  if(index(num)>max_len_){
     max_len_ = index(num);
  }
  byte_[index(num)] |= 1<<position(num); //将对应的位置置为1,去重很方便,但是如果不去冲的话需要考虑加key;
}
//可以确定这个数字是否存在用来进行后续的操作,
bool BitMap::contain(int num){
  return ((byte_[index(num)]&(1<<position(num)))!=0);
}


void BitMap::clear(int num){
  byte_[index(num)] &=(~(1<<position(num)));
}
//可以通过图绘;
void BitMap::add_array(int* array,int size){
  for(int i=0; i<size; i++){
     add(array[i]);
  }
}
void BitMap::sort_and_show(){//这些是不重复的;
  //这里实际上需要知道 array的范围进行取舍,或者知道数量的范围;
  // byte转换;
  int change = 1;
  std::cout<<"the max len is"<<max_len_<<std::endl;
  for(int i=0; i<=max_len_; i++){
     //优化一下;考虑有可能位全空;
     if(0 == (byte_[i] | 0)) continue;
     for(int j=0; j<=7; j++){
       if(0!=(byte_[i]&(change<<j))){  //这一块出问题了;
         //证明这一位存在;
         std::cout<<i*8+j<<" ";
       }
       change = 1;
     }
  }
}
void BitMap::show_every_bit(char ch){
  for(int i=0; i<=7; i++){
     std::cout<<((ch>>i)&1)<<" ";
  }
}
void BitMap::show_bit(){
  for(int i=0; i<alloc_size_; i++){
    show_every_bit(byte_[i]);
    std::cout<<std::endl;
  }
}
/*
void BitMap::sort_and_show(vector<int> array){
  for(int i=0 ; i<array.size(); i++){
     add(array[i]);
  }
  int change =1 ;
  for(int i=0; i<=max_len; i++){
     if(0 == (bytes[i] | 0)) continue;
     for(int j=0; j<=7; j++){
       if(0!=(byte_[i]&(~(change<<j)))){
         //证明这一位存在;
         cout<<i*8+j<<" ";
       }
       change = 1;
     }
  }

}*/

BitMap.h

#ifndef BITMAP_H_INCLUDED
#define BITMAP_H_INCLUDED
#include<vector>
class BitMap{
  public:
     BitMap();
     BitMap(int size);
     ~BitMap();
     void add(int num);
     bool contain (int num);
     void clear(int num);


     void add_array(int* array,int size);
     void sort_and_show();
//     void sort_and_show(vector<int> array);
     inline index(int index){return (index/8);}
     inline position(int pos){return (pos & 0x07);}
     void show_bit();
     void show_every_bit(char ch);
  private:
     int alloc_size_; // 标定起始的byte数组的大小;
     int max_len_;    // 表明当前的实际长度;
     char* byte_;  //还需要区分32与 8的区别;
     BitMap(const BitMap&);
     BitMap& operator=(const BitMap&);
     //inline index(int index){return (index>>8);}
     //inline position(int pos){return (pos & 0x07);}
     //void show_every_bit(char ch);
};

#endif // BITMAP_H_INCLUDED

main部分:

#include<iostream>
#include"BitMap.h"
using namespace std;
int main(){
    BitMap map_;
    int a[10]= {1,5,8,9,12,45,13,48,56,57};
    map_.add_array(a,10);
    map_.sort_and_show();
    cout<<endl;
    //map_.show_bit();
    return 0;
}


``

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值