因为数组在内存中是一段连续的空间,所以数字的位连续起来,可以表示是一个超大的数字
例如这个样子,代表一个数字
左移运算符(<<)
腾出的位置用0填充,超出边界的位将被丢弃
右移运算符(>>)
对于无符号整数,腾出的位置用0填充,超出边界的位将被丢弃
对于有符号整数,腾出的位置用1填充,超出边界的位将被丢弃
非运算符(~)
0的位变1,1的位变0
与运算符(&)
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 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
打开位
num表示操作数,pos + 1表示操作数的第pos + 1位
1 num |= (1 << pos); 2 num = num | (1 << pos);
因为1和0同1做或运算得到1,所以打开了位。
而1和0同0做或运算得到其本身,所以对其他位无影响。
切换位
num表示操作数,pos + 1表示操作数的第pos + 1位
1 num ^= (1 << pos); 2 num = num ^ (1 << pos);
因为1与1做异或运算得到0,0与1做异或运算得到1,所以就把打开位关闭,把关闭位打开
而1和0同0做异或运算得到的其本身,所以对其他位无影响
关闭位
num表示操作数,pos + 1表示操作数的第pos + 1位
1 num &= ~(1 << pos); 2 num = num & ~(1 << pos);
因为1和0同0做与运算得到0,所以关闭了位
而1和0同1做与运算得到其本身,所以对其他位无影响
测试位(是否为1)
num表示操作数,pos + 1表示操作数的第pos + 1位
1 num & (1 << pos);
因为1和0同0做与运算得到0,所以除了第pos + 1位的其他所有为都被设置为0
而1和0同1做与运算得到其本身,所以,当第pos + 1位是1时,改表达式的值得到1,否则,得到0
我们需要设定几个函数
1 void set(int pos); //把位置pos设置成1 2 void reset(int pos); //将位置pos设置成0 3 int count() const; //输出一共有多少个为1的位 4 bool test(int pos) const; //位置pos是否是1 5 bool any() const; //是否有是1的位 6 bool none() const; //是否没有是1的位 7 bool all() const; //是否所有位都是1
以下是类声明文件的代码,因为我们要实现的是数组位操作,所以需要完成运算符的重载
1 #ifndef BITSET_H 2 #define BITSET_H 3 4 #include<iostream> 5 class bitset { 6 private: 7 int* a; 8 int size; 9 public: 10 bitset(int s = 0); 11 ~bitset(); 12 void set(int pos); 13 void reset(int pos); 14 int count() const; 15 bool test(int pos) const; 16 bool any() const; 17 bool none() const; 18 bool all() const; 19 20 bitset& operator&= (const bitset& b); 21 bitset& operator|= (const bitset& b); 22 bitset& operator^= (const bitset& b); 23 bitset& operator= (const bitset& b); 24 bitset& operator <<= (int pos); 25 bitset& operator >>= (int pos); 26 bitset operator~() const; 27 bitset operator&(const bitset& b) const; 28 bitset operator|(const bitset& b) const; 29 bitset operator^(const bitset& b) const; 30 bitset operator<<(int pos) const; 31 bitset operator>>(int pos) const; 32 bool operator== (const bitset& b) const; 33 bool operator!= (const bitset& b) const; 34 bool operator[] (int pos) const; 35 friend std::ostream& operator << (std::ostream& os, const bitset& s) 36 }; 37 38 #endif
接下来重点谈谈,左移与右移的重载
左移:
为了简化,我将以4位数字来代表一个整数
对此,我们进行左移,最直接的想法应该就是使用一个循环来让数组的每一个数都左移相同的pos吧
但是这么做会出现这样的情况,假如pos是1
左移后是
而实际上应该是
因此,我们在对a[i]移位后,要判断a[i - 1]的最左边的位是否为1,如果是1则需要将a[i]的最右边的位设定为1
右移:
同样为了简化,我将以4位数字来代表一个整数,并沿用上面的例子
最简单是思想还是使用一个循环来让数组的每一个数都右移相同的pos吧
但是这么做会出现这样的情况,假如pos是1
右移后是
而实际上应该是
因此,我们在对a[i]移位后,要判断a[i + 1]的最右边的位是否为1,如果是1则需要将a[i]的最左边的位设定为1,否则设定为0
至此,这个类最难的地方结束,下面是类定义文件的代码
1 #include"Bitset.h" 2 3 bitset::bitset(int s) : size(s) { 4 a = new int[size]; 5 for (int i = 0; i < size; i++) 6 a[i] = 0; 7 } 8 9 bitset::~bitset() { 10 delete[] a; 11 size = 0; 12 } 13 14 void bitset::set(int pos) { 15 int x = pos / 32; 16 int y = pos % 32; 17 a[x] |= 1 << y; 18 } 19 20 void bitset::reset(int pos) { 21 int x = pos / 32; 22 int y = pos % 32; 23 a[x] &= ~(1 << y); 24 } 25 26 int bitset::count() const { 27 int sum = 0; 28 for (int i = 0; i < 32 * size; i++) 29 if (test(i)) sum++; 30 return sum; 31 } 32 33 bool bitset::test(int pos) const { 34 int x = pos / 32; 35 int y = pos % 32; 36 return (a[x] & (1 << y)); 37 } 38 39 bool bitset::any() const { 40 return count() > 0; 41 } 42 43 bool bitset::none() const { 44 return count() == 0; 45 } 46 47 bool bitset::all() const { 48 return count() == 32 * size; 49 } 50 51 bitset& bitset::operator&= (const bitset& b) { 52 for (int i = 0; i < size; i++) a[i] &= b.a[i]; 53 return *this; 54 } 55 56 bitset& bitset::operator|= (const bitset& b) { 57 for (int i = 0; i < size; i++) a[i] |= b.a[i]; 58 return *this; 59 } 60 61 bitset& bitset::operator^= (const bitset& b) { 62 for (int i = 0; i < size; i++) a[i] ^= b.a[i]; 63 return *this; 64 } 65 66 bitset& bitset::operator <<= (int pos) { 67 while (pos--) { 68 for (int i = size - 1; i >= 0; i--) { 69 a[i] <<= 1; 70 if (i != 0) { 71 if (a[i - 1] & (1 << 31)) 72 a[i] |= 1; 73 } 74 } 75 } 76 return *this; 77 } 78 79 bitset& bitset::operator>>= (int pos) { 80 while (pos--) { 81 for (int i = 0; i < size; i++) { 82 a[i] >>= 1; 83 if (i != size - 1) { 84 if (a[i + 1] & 1) 85 a[i] |= 1 << 31; 86 else 87 a[i] &= ~(1 << 31); 88 } 89 } 90 } 91 return *this; 92 } 93 94 bitset& bitset::operator= (const bitset& b) { 95 for (int i = 0; i < size; i++) a[i] = b.a[i]; 96 return *this; 97 } 98 99 bitset bitset::operator~() const { 100 bitset s; 101 for (int i = 0; i < size; i++) s.a[i] = ~a[i]; 102 return s; 103 } 104 105 bitset bitset::operator& (const bitset& b) const { 106 bitset s; 107 s = *this; 108 return s &= b; 109 } 110 111 bitset bitset::operator| (const bitset& b) const { 112 bitset s; 113 s = *this; 114 return s |= b; 115 } 116 117 bitset bitset::operator^ (const bitset& b) const { 118 bitset s; 119 s = *this; 120 return s ^= b; 121 } 122 123 bitset bitset::operator << (int pos) const { 124 bitset s; 125 s = *this; 126 return s <<= pos; 127 } 128 129 bitset bitset::operator >> (int pos) const { 130 bitset s; 131 s = *this; 132 return s >>= pos; 133 } 134 135 bool bitset::operator== (const bitset& b) const { 136 for (int i = 0; i < size; i++) 137 if (a[i] != b.a[i]) return false; 138 return true; 139 } 140 141 bool bitset::operator!= (const bitset& b) const { 142 for (int i = 0; i < size; i++) 143 if (a[i] != b.a[i]) return true; 144 return false; 145 } 146 147 bool bitset::operator[] (int pos) const { 148 return test(pos); 149 } 150 151 std::ostream& operator << (std::ostream& os, const bitset& s) { 152 for (int i = s.size - 1; i >= 0; i--) { 153 for (int j = 31; j >= 0; j--) { 154 if (s.a[i] & (1 << j)) os << 1; 155 else os << 0; 156 } 157 } 158 return os; 159 }
原文:http://www.cnblogs.com/alan23/p/5285907.html