~位图(补充)~

来源:互联网 发布:网吧会员软件 编辑:程序博客网 时间:2024/05/29 16:59

       上一篇博客中讲到的位图只能判断数据是否存在,但并不能判断该数据是只存在1个还是存在多个,这就是一个小小的缺陷!没事,稍改代码就可以弥补这一缺陷。

 

       方便实现代码,我们假设数组的数据类型为int,则位图所实现的接口如下:

0.初始化数组

  设数据的范围为range,开辟一个大小为(range>>4)+1的数组,并使其初始化为0。

BitSet(size_t range){_set.resize((range >> 4) + 1, 0);}

1.确定数据应存入的位置

  设要存入的数据为num,index表示的是存入数组的哪个数据中,pos表示的是存入数据的哪位二进制位中。

size_t index = num >> 5;size_t pos = (num % 16) * 2;

2.设置数据

  用2位二进制位表示一个数据,其中00表示数据不存在,01表示只存在1个,11表示数据存在多个。

void set(size_t num){size_t index = num >> 5;size_t pos = (num % 16) * 2;if((_set[index] & (1 << pos)) == 0){_set[index] |= (1 << pos);}else{_set[index] |= (1 << pos);++pos;_set[index] |= (1 << pos);}}

3.清除数据

  该自定义类不能设计清除数据这一接口,因为在清除数据时,若数据存在时无法判断数据是存在1个还是多个。

4.判断数据是否存在

   若输出为0表示数据不存在,输出为1表示数据存在1个,输出为2表示数据存在多个。

int Test(size_t num){size_t index = num >> 5;size_t pos = (num % 16) * 2;if((_set[index] & (1 << pos)) == 0){return 0;}else if((_set[index] & (1 << pos)) && (_set[index] & (1 << (++pos))) == 0){return 1;}else{return 2;}}

 

完整的源代码及测试用例如下:

#include <vector>class BitSet{public:BitSet(size_t range){_set.resize((range >> 4) + 1, 0);}void set(size_t num){size_t index = num >> 5;size_t pos = (num % 16) * 2;if((_set[index] & (1 << pos)) == 0){_set[index] |= (1 << pos);}else{_set[index] |= (1 << pos);++pos;_set[index] |= (1 << pos);}}int Test(size_t num){size_t index = num >> 5;size_t pos = (num % 16) * 2;if((_set[index] & (1 << pos)) == 0){return 0;}else if((_set[index] & (1 << pos)) && (_set[index] & (1 << (++pos))) == 0){return 1;}else{return 2;}}protected:vector<int> _set;};void TestBitSet(){BitSet s(1000);s.set(1);s.set(1);s.set(8);cout<<s.Test(1)<<endl;cout<<s.Test(8)<<endl;cout<<s.Test(33)<<endl;}

 

 

 

0 0