编程珠玑位逻辑运算实现位向量

看编程珠玑时,看到位逻辑运算实现位向量,思考了一些时间,做一些注释。

/*位图数据结构:该数据结构描述了一个有限定义域内的稠密集合,其中每个元素最多出现一次并且没有其他任何数据结构与该元素相关联*/
#include<iostream>
#define BITSPERWORD 32
#define N 10000000
#define SHIFT 5
#define MASK 0x1F
using namespace std;
int a[1+ N / BITSPERWORD];
/*N表示的是需要用位向量存储数据的最大值,因为C++中int类型由4个字节表示,
因此有32位,那么我们可以用(N/32+1)个int来表示这些数据,比如a[0]表示的范围是0-31,a[1]表示的范围是32-63,以此类推。
那么站在位的角度来看,数组a就是一个(N/32+1) × 32的位矩阵,那么就下来的任务就是确定每一个数在这个矩阵中的位置,行号和列号,找到后将该位置置1*/
void set(int i){
    /*i >> SHIFT表示的是i在数组中的位置(也就是位矩阵的行数),可以改写成i/SHIFT;
    i & MASK则表示的是i在这一行中的列数,MASK的值是0x1F,也就31,i & MASK形成了一个i与0-31(列编号)之间的一一映射,
则表示形成一个所在列为1其他位置为0的32位2进制串(1右移列编号的位数),与a[i >> SHIFT]进行或操作后相当于将i在位矩阵中的位置值置1*/
    a[i >> SHIFT] |= 1 << (i & MASK);
}
void clear(int i){
    /*原理和set函数相近,首先找到i在位矩阵中的位置,其次将该位置的值置0,i >> SHIFT表示行号,
    i & MASK表示列号,a[i >> SHIFT] &= ~(1 << (i & MASK))是置0操作*/
    a[i >> SHIFT] &= ~(1 << (i & MASK));
}
int test(int i){
    /*找到i所在的位置,进行与操作,如果该数存在那么结果非0,否则结果为0*/
    return a[i >> SHIFT] & (1 << (i & MASK));
}
int main(){
    set(100);
    cout<<test(100)<<endl;
    clear(100);
    cout<<test(100)<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值