位向量是一种用来记录一组项目或条件的是/否标志,c++语言中的位操作符允许程序员设置或测试位向量中独立的位或位域。举例来说,可以用一个位向量来记录一个32个学生的班级中一次测试的结果,第i位代表了学号为i的学生(假设学号从0开始)是否通过了本次测试。(位置1表示通过,置0表示未通过),(注:以下内容默认机器为32位) 过程如下: /*将所有位置0*/ unsigned int quiz=0; /*将pos位置1*/ inline void set(unsigned int & ui,int pos){ ui|=(1<<pos); } /*将pos位置0*/ inline void clr(unsiged int & ui,int pos){ ui&=~(1<<pos); } /*将pos位翻转*/ inline void flip(unsiged int & ui,int pos){ ui^=(1<<pos); } /*测试pos位是否为1*/ inline void test(unsiged int & ui,int pos){ return ui&(1<<pos); } 下面的问题在于如果这个班级的大于32个人,比如说100人该如何去处理呢?很显然,我们需要(1+100/32)个字去记录这些位,方法是将这些字组成一个数组,数组中的第i个字记录了从第i位到第i+31位的标志。 代码如下: /*以下3个值由32位机器确定,如果机器位64位,则做相应改动*/ #define BITSPERWORD 32 #define SHIFT 5 #define MASK 0x1F #define N 100 unsigned 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)); } void flip(int i){ a[i>>SHIFT]^=(1<<(i&MASK)); } bool test(int i){ return a[i>>SHIFT] & (1<<(i&MASK)); } 幸运的是,c++为我们提供了bitset类,可以方便的定义一个大于32位的位向量,并且提供了现成的 set,reset,flip等操作,其内部实现也应该采用的是上述方法。对于c++用户应该尽量使用bitset类。 参阅书籍:C++Primer Programming Pearls

|