[Programming Pearls]1.2 & 1.3
给定一个整型(32位)数组,输入一个参数i,然后设置数组的i位(bit位)是1,或者对第i位清零,或者探测第i位的值。使用位逻辑运算(例如与、或、移位)来实现位向量。
// 如何使用位逻辑运算(例如与、或、移位)来实现位向量
// 下面的函数使用常量来设置、清除以及测试位值
// 将位图存储在一个整型数组里面
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD]; //将位图保存在整型数组中
void set(int i) { a[i>>SHIFT] |= (1<<(i & MASK)); }
void clr(int i) { a[i>>SHIFT] &= ~(1<<(i & MASK));}
int test(int i){ return a[i>>SHIFT] & (1<<(i & MASK)); }
其中set方法将对应的bit位置值设为0或者1,其中i>>SHIFT即i/32即求出所需要set的bit位位于整型数组的哪个整数值中。而i&MASK即i%32判断该bit位在该整数的什么位置。然后进行|运算即可将该bit位在整型数组的值正确设置。clr函数即将相应bit位的值清0。test函数即测试相应bit位的值是否为0,若为0则返回0,否则返回1。
故上述函数也可以改写如下:
void set(int i) { a[i/32] |= (1<<(i%32)); }
void clr(int i) { a[i/32] &= ~(1<<(i%32)); }
int test(int i) { return a[i/32] & (1<<(i%32)); }
以下利用上述函数实现位图排序算法。
具体问题如下:运行时效率是设计目标的一个重要组成部分,所得到的程序需要足够高校。在你自己的系统上实现位图排序并度量其运行时间。假设n为10000000,且输入文件包含1000000个整数。
// 实现位图排序
int main(void)
{
int i;
for(i=0; i<N; ++i)
clr(i);
while(scanf("%d",&i) != EOF)
set(i);
for(i=0; i<N; ++i)
if(test(i))
printf("%d\n",i); // 按照位图输出为1的位置
return 0;
}