位运算符在我们实际项目的应用可能比较少,久而久之可能就忘什么是按位运算符?今天刚好遇到关于按运算的实际应用。为了方便以后查询及加深自己对位运算符的理解,特此记录相关的知识点。我们首先回顾一下什么是按位运算符?
位运算:我们都知道计算存储数值是二进制表示的。位运算就是直接对二进制进行运算。主要分为 与“$”, 或"|",非“~”和或异“^”运算符
- 与运算符($)
0&0=0,0&1=0,1&0=0,1&1=1 - 或运算符(|)
0&0=0,0&1=1,1&0=1,1&1=1 - 非(~)运算
取反。0->1,1->0. a=0111, ~a = 1000 - 异或(^)运算
同为假,异为真 所以它是这样的算法: 0&0=0,0&1=1,1&0=1,1&1=0 - << 左移运算符
1 << 3
- ">>"右移运算符
1 >> 3
应用
- 设置flags
#define XT_FIND_BOND (1 << 4)
#define XT_FIND_SSSR (1 << 5)
#define SET_OR_UNSET_FLAG(X) \
if(value) setFlag(X);
else unsetFlag(X);
class Mol
{
private:
unsigned int _flags;
void setFlag(int flag) {_flags |= flag;}
void unsetFlag(int flag) { _flags &= (~(flag));}
bool hasFlag(int flag) {return (_flags & flag)!=0;}
public:
Mol():_flags(0){}
void setSSSRFlag(bool value=true){SET_OR_UNSET_FLAG(XT_FIND_SSSR)} //设置 SSSR 标签
bool isSetSSSRFlag() const {return hasFlag(XT_FIND_SSSR);}
}
基于位运算符操作,我们可以高效地为Mol设置各种flag。
2 . 从整数中寻找出现一次的数
int x[] = {1, 3, 1, 3, 4, 5};
int res = 0;
for (int i:x) {
res ^= i;
}
// 寻找整数中恰好只有一个整数出现2次的数
int x1[] = {1, 2, 3, 4, 5, 6,2};
int res1 = 0;
int i = 1;
int n = sizeof(x1) / sizeof(int);
while (i < n) {
res1 ^= i;
res1 ^= x1[i];
i++;
}
res1 ^= x1[0];