C++ bitset(2)实现
1 为了区分C++标准库中的bitset数据结构,在本程序中使用_bitset。 2 3 如果设置_bitset的长度为4,则可操作的位为0-3。 4 5 //_bitset.h 6 7 #ifndef _BITSET_H 8 #define _BITSET_H 9 10 #include <limits> 11 #include <cstring> 12 #include <iostream> 13 using namespace std; 14 15 class _bitset 16 { 17 friend ostream & operator << (ostream & out,const _bitset & elem); //重载输出操作符public: typedef unsigned long block_type; //最小存储单元块的类型 typedef unsigned long size_type; //最小存储单元块的大小类型 18 19 private: 20 enum {BLOCK_BYTES = sizeof(block_type)}; //最小存储单元块的字节数 enum {BLOCK_BITS = std::numeric_limits<block_type>::digits}; //最小单元存储块的位数,平台通用性,所以使用numeric_limits 21 22 public: 23 _bitset(); 24 _bitset(size_type val); 25 _bitset(const _bitset & val); 26 _bitset & operator=(const _bitset & val); 27 ~_bitset(); 28 29 _bitset & operator <<= (size_type num); //左移赋值操作 30 _bitset & operator >>= (size_type num); //右移赋值操作 31 32 _bitset & set(size_type pos,bool tagSet = true); //设置bitset中的某一位的值 33 _bitset & clear(bool tagClear = true); //使得bitset中每一位都为0 34 35 _bitset & flip(); //反转所有位操作 36 _bitset & operator ~(); //取反操作符 37 38 _bitset & flip(size_type pos); //反转pos位的操作 39 40 bool test(size_type pos) const; //测试相应位是1还是0 41 42 _bitset & operator &= (const _bitset & val); 43 _bitset & operator |= (const _bitset & val); 44 _bitset & operator ^= (const _bitset & val); 45 bool operator == (const _bitset & val) const; 46 47 size_type size() const; 48 49 private: 50 void leftShift(size_type num); //左移操作 51 void rightShift(size_type num); //右移操作 52 53 private: 54 size_type m_bitNum; //bitset中位的个数 size_type m_size; //block_type的个数 55 56 block_type * m_pBits; //存储bit位 57 block_type m_mask; //假如bitset的位数是5,而m_pBits[0]=0xFFFFFFFF,m_mask用来表示 //m_pBits[0]的后5位有效}; 58 59 _bitset operator << (const _bitset &,_bitset::size_type); 60 _bitset operator >> (const _bitset &,_bitset::size_type); 61 _bitset operator & (const _bitset &,const _bitset &); 62 _bitset operator | (const _bitset &,const _bitset &); 63 _bitset operator ^ (const _bitset &,const _bitset &); 64 65 inline _bitset::_bitset(size_type bitNum) 66 { 67 m_bitNum = bitNum; 68 size_type free_bits = (BLOCK_BITS - m_bitNum % BLOCK_BITS) % BLOCK_BITS; 69 m_size = m_bitNum / BLOCK_BITS + (free_bits == 0 ? 0 : 1); 70 m_pBits = new block_type[m_size]; 71 72 if (m_pBits == NULL) 73 { 74 cout << "no enough memorry!\n"; 75 exit(0); 76 } 77 78 clear(); 79 m_mask = ~block_type(0); 80 m_mask >>= free_bits; 81 } 82 83 inline _bitset::_bitset(const _bitset &val) 84 { 85 m_size = val.m_size; 86 m_pBits = new block_type[m_size]; 87 if (m_pBits == NULL) 88 { 89 cout << "no enough memorry!\n"; 90 exit(0); 91 } 92 memcpy(m_pBits,val.m_pBits,m_size * BLOCK_BYTES); 93 m_bitNum = val.m_bitNum; 94 m_mask = val.m_mask; 95 } 96 97 inline _bitset & _bitset::operator =(const _bitset &val) 98 { 99 if (this == &val) 100 return (*this); 101 102 if (m_size != val.m_size) 103 { 104 delete [] m_pBits; 105 m_size = val.m_size; 106 m_pBits = new block_type[m_size]; 107 if (m_pBits == NULL) 108 { 109 cout << "no enough memorry!\n"; 110 exit(0); 111 } 112 } 113 memcpy(m_pBits,val.m_pBits,m_size * BLOCK_BYTES); 114 m_bitNum = val.m_bitNum; 115 m_mask = val.m_mask; 116 return (*this); 117 } 118 119 inline _bitset::~_bitset() 120 { 121 delete [] m_pBits; 122 } 123 124 inline _bitset & _bitset::operator <<=(_bitset::size_type num) 125 { 126 leftShift(num); 127 return (*this); 128 } 129 130 inline _bitset & _bitset::operator >>=(_bitset::size_type num) 131 { 132 rightShift(num); 133 return (*this); 134 } 135 136 inline _bitset::size_type _bitset::size() const 137 { 138 return m_bitNum; 139 } 140 141 inline _bitset & _bitset::flip() 142 { 143 for (size_type i=0;i<m_size;++i) 144 m_pBits[i] = ~m_pBits[i]; 145 m_pBits[m_size-1] &= m_mask; 146 147 return (*this); 148 } 149 150 inline _bitset & _bitset::operator~() 151 { 152 return _bitset(*this).flip(); 153 } 154 155 inline _bitset & _bitset::operator &=(const _bitset &val) 156 { 157 if (m_bitNum != val.m_bitNum) 158 { 159 cout << "different length\n"; 160 exit(0); 161 } 162 for (size_type i=0;i<m_size;i++) 163 m_pBits[i] &= val.m_pBits[i]; 164 return (*this); 165 } 166 167 inline _bitset & _bitset::operator |=(const _bitset &val) 168 { 169 if (m_bitNum != val.m_bitNum) 170 { 171 cout << "different length\n"; 172 exit(0); 173 } 174 for (size_type i=0;i<m_size;i++) 175 m_pBits[i] |= val.m_pBits[i]; 176 return (*this); 177 } 178 179 inline _bitset & _bitset::operator ^=(const _bitset &val) 180 { 181 if (m_bitNum != val.m_bitNum) 182 { 183 cout << "different length\n"; 184 exit(0); 185 } 186 for (size_type i=0;i<m_size;i++) 187 m_pBits[i] ^= val.m_pBits[i]; 188 return (*this); 189 } 190 191 inline bool _bitset::operator ==(const _bitset &val) const 192 { 193 if (m_bitNum != val.m_bitNum) 194 return false; 195 for (size_type i=0;i < m_size;++i) 196 if (m_pBits[i] != val.m_pBits[i]) 197 return false; 198 199 return true; 200 } 201 202 inline _bitset operator << (const _bitset & val,_bitset::size_type num) 203 { 204 return _bitset(val) <<= num; 205 } 206 207 inline _bitset operator >> (const _bitset & val,_bitset::size_type num) 208 { 209 return _bitset(val) >>= num; 210 } 211 212 inline _bitset operator | (const _bitset & l,const _bitset & r) 213 { 214 return _bitset(l) |= r; 215 } 216 217 inline _bitset operator & (const _bitset & l,const _bitset & r) 218 { 219 return _bitset(l) &= r; 220 } 221 222 inline _bitset operator ^ (const _bitset & l,const _bitset & r) 223 { 224 return _bitset(l) ^= r; 225 } 226 227 inline _bitset & _bitset::clear(bool tagClear) 228 { 229 if (tagClear) 230 { 231 memset(m_pBits,0,m_size * BLOCK_BYTES); 232 } 233 else 234 { 235 memset(m_pBits,std::numeric_limits<unsigned char>::max(),m_size * BLOCK_BYTES); 236 m_pBits[m_size-1] &= m_mask; 237 } 238 return (*this); 239 } 240 241 #endif 242 243 244 245 //_bitset.cpp 246 247 #include "_bitset.h" 248 249 void _bitset::leftShift(_bitset::size_type num) 250 { 251 if (num >= m_bitNum) 252 { 253 clear(); 254 return; 255 } 256 257 size_type eleNum = num / BLOCK_BITS; 258 size_type bitNum = num % BLOCK_BITS; 259 260 if (eleNum != 0) 261 { 262 block_type * pTmp = new block_type[m_size]; 263 if (pTmp == NULL) 264 { 265 cout << "no enough memory\n"; 266 exit(0); 267 } 268 memcpy(pTmp,m_pBits,(m_size-eleNum)*BLOCK_BYTES); 269 memcpy(m_pBits+eleNum,pTmp,(m_size-eleNum)*BLOCK_BYTES); 270 memset(m_pBits,0,eleNum*BLOCK_BYTES); 271 delete [] pTmp; 272 } 273 274 if (bitNum != 0) 275 { 276 block_type * pTmp = m_pBits + m_size -1; 277 for (;pTmp > m_pBits;--pTmp) 278 { 279 *pTmp = (*pTmp << bitNum) | (*(pTmp-1) >> (BLOCK_BITS - bitNum)); //*pTmp的地位或上(*(pTmp-1))的高位 280 } 281 *pTmp <<= bitNum; 282 } 283 284 m_pBits[m_size-1] &= m_mask; //将数组最高位的元素无用位置0} 285 286 void _bitset::rightShift(_bitset::size_type num) 287 { 288 if (num >= m_bitNum) 289 { 290 clear(); 291 return; 292 } 293 size_type eleNum = num / BLOCK_BITS; 294 size_type bitNum = num % BLOCK_BITS; 295 296 if (eleNum != 0) 297 { 298 block_type * pTmp = new block_type[m_size]; 299 if (pTmp == NULL) 300 { 301 cout << "no enough memory\n"; 302 exit(0); 303 } 304 305 memcpy(pTmp,m_pBits+eleNum,(m_size-eleNum)*BLOCK_BYTES); 306 memcpy(m_pBits,pTmp,(m_size-eleNum)*BLOCK_BYTES); 307 memset(m_pBits+m_size-eleNum,0,eleNum * BLOCK_BYTES); 308 delete [] pTmp; 309 } 310 311 if (bitNum != 0) 312 { 313 block_type * pTmp = m_pBits; 314 for (;pTmp < m_pBits + m_size -1;++pTmp) 315 { 316 *pTmp = (*pTmp >> bitNum) | (*(pTmp+1) << (BLOCK_BITS - bitNum)); 317 } 318 *pTmp >>= bitNum; 319 } 320 } 321 322 _bitset & _bitset::set(size_type pos,bool tagSet) 323 { 324 if (pos > m_bitNum || pos < 0) 325 { 326 cout << "position is not right\n"; 327 exit(0); 328 } 329 330 size_type eleNum = pos / BLOCK_BITS; 331 size_type bitNum = pos % BLOCK_BITS; 332 333 block_type mask = 1; 334 mask <<= bitNum; 335 336 if (tagSet) 337 { 338 m_pBits[eleNum] |= mask; 339 } 340 else 341 { 342 m_pBits[eleNum] &= ~mask; 343 } 344 return (*this); 345 } 346 347 _bitset & _bitset::flip(_bitset::size_type pos) 348 { 349 if (pos > m_bitNum || pos < 0) 350 { 351 cout << "position is not right\n"; 352 exit(0); 353 } 354 355 size_type eleNum = pos / BLOCK_BITS; 356 size_type bitNum = pos % BLOCK_BITS; 357 358 block_type mask = 1; 359 mask <<= bitNum; 360 m_pBits[eleNum] = m_pBits[eleNum] ^ mask; 361 return (*this); 362 } 363 364 bool _bitset::test(_bitset::size_type pos) const 365 { 366 if (pos > m_bitNum || pos < 0) 367 { 368 cout << "position is not right\n"; 369 exit(0); 370 } 371 372 size_type eleNum = pos / BLOCK_BITS; 373 size_type bitNum = pos % BLOCK_BITS; 374 375 block_type mask = 1; 376 mask <<= bitNum; 377 378 return m_pBits[eleNum] & mask; 379 } 380 381 ostream & operator << (ostream & out,const _bitset & elem) 382 { 383 _bitset::size_type j = 0; 384 _bitset::size_type mask = 1; 385 mask <<= (elem.m_bitNum % _bitset::BLOCK_BITS-1); 386 387 for (_bitset::size_type i = elem.m_bitNum-1;i>0;i--) 388 { 389 if (i % (_bitset::BLOCK_BITS) == 0) 390 { 391 j++; 392 mask = 1; 393 mask <<= (_bitset::BLOCK_BITS-1); 394 } 395 if (elem.m_pBits[elem.m_size-j-1] & mask) 396 { 397 out << 1; 398 } 399 else 400 { 401 out << 0; 402 } 403 mask >>= 1; 404 } 405 return out; 406 } 407 408 409 410 //main 测试函数 411 412 #include <iostream> 413 #include <bitset> 414 #include <limits> 415 #include "_bitset.h" 416 using namespace std; 417 418 int main() 419 { 420 bitset<4> mybits; 421 //cout << mybits << endl; 422 cout << mybits.set(3) << endl; 423 424 _bitset bit(34); 425 bit.set(33); 426 //bit.rightShift(1); 427 //bit <<= 1; 428 cout << bit << endl; 429 } 430 431 bitset数据结构能够有效的节约存储空间,在海量数据排序,海量数据检索中都有用处。