位向量是一种高效的整数结构,每一个32位的整数通过设置或清除它的某一位,可以保存32个数。如果是一个数组,则可以存更多的数。
先介绍一下对2的n次方求模的另一种方法。
如果x = 2,4,8,16,32,64,128...,则y%x = y & (x-1),(y为任意正整数)
下面介绍位向量的结构:
class BitVec {
private:
enum { BITSPERWORD = 32, SHIFT = 5, MASK = 0x1F };
int number, upper_limit, *data;
public:
BitVec(int max = 0):upper_limit(max)
{
data = new int[1 + upper_limit>>SHIFT];
memset(data,0,sizeof(int)*(1+upper_limit>>SHIFT));
number = 0;
}
~BitVec()
{
delete[] data;
number = upper_limit = 0;
}
void set(int i) { data[i>>SHIFT] |= (1<<(i & MASK)); }
void clr(int i) { data[i>>SHIFT] &= ~(1<<(i & MASK));}
bool test(int i) { return data[i>>SHIFT]&(1<<(i & MASK)); }
void insert(int i)
{
set(i);
++number;
}
void report(int *v)
{
int j = 0;
for(int i = 0; i <= upper_limit; ++i)
if(test(i))
v[j++] = i;
}
};
其中:data[i>>SHIFT]是找出i用data的第几个元素来表示。比如说,如果i = 33,而一个int只有32位(0-31),因此它在data[1]的第2位表示。顺便提一下,上面用到了enum,有两种方法可以在类内部使用初始化后的成员变量,一种是用enum,另一种是static const。
既然已经解决了数的存储问题,下一步就可以用这个类来进行排序,想法类似于桶排序,先放进去,再按序取出。
const int MAXVALUE = 100;
void bitsort(int *arr, int lengthofarr)
{
BitVec bv(MAXVALUE);
for(int i = 0; i < lengthofarr; ++i)
{
bv.insert(arr[i]);
}
bv.report(arr);
}