C++Notes(2)--关于位运算

类别:编程语言 点击:0 评论:0 推荐:

位向量是一种用来记录一组项目或条件的是/否标志,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

本文地址:http://com.8s8s.com/it/it21791.htm