自己用C++实现的Bitset类, 功能参考STL的bitset类, 由于VS2005不支持模板的分离编译, 所以都实现在了一个名为Bitset.h的头文件里. 肯定有一些bug, 请各位高手帮忙抓虫. 抛砖引玉, 博大家一晒.
1: #ifndef BIT_SET_H2: #define BIT_SET_H
3: //Readme
4: //本程序实现了一个类似std::bitset的类, 经过了一些测试,
5: //但还没有全面测试
6: 7: #include <iosfwd> //前导定义
8: #include <string>
9: #include <cstdlib>10: #include <string>
11: #include <algorithm> 12: #ifdef EXCEPTION_HANDLE13: #include "exception.h"
14: #endif
15: using std::string;
16: using std::ostream;
17: 18: //Utility macros
19: #define CHAR_BITS 8
20: #define WORD_LEN (sizeof(unsigned int) * CHAR_BITS )
21: #define BITSET_WORD_CNT(n) ((n + WORD_LEN -1) / WORD_LEN) //辅助宏
22: 23: typedef unsigned int WORD;
24: 25: namespace imgen
26: { 27: template<size_t sz>28: class bitset
29: {30: class bit //辅助类,将比特位抽象为一个类,为bitset类服务
31: {32: private:
33: bitset<sz>& bs; 34: size_t pos; 35: 36: public:
37: bit(bitset& bs, size_t pos):bs(bs),pos(pos){} 38: 39: //提供一系列操作
40: void flip()
41: { 42: bs.flip(pos); 43: } 44: 45: void set()
46: { 47: bs.set(pos); 48: } 49: 50: void reset()
51: { 52: bs.reset(pos); 53: } 54: 55: bool test()const
56: {57: return bs.test(pos);
58: } 59: 60: //bool类型转换操作符
61: operator bool()const
62: {63: return test();
64: } 65: 66: //赋值操作符
67: bit& operator = (int n)
68: {69: if(n != 0)
70: bs.set(pos);71: else
72: bs.reset(pos);73: return *this;
74: } 75: 76: //赋值操作符
77: bit& operator = (const bit&rhs)
78: {79: if(rhs.test())
80: bs.set(pos);81: else
82: bs.reset(pos);83: return *this;
84: } 85: 86: //赋值操作符
87: bit& operator = (bool b)
88: {89: if(b)
90: bs.set(pos);91: else
92: bs.reset(pos); 93: 94: return *this;
95: } 96: 97: bool operator !()
98: {99: return !test();
100: } 101: }; 102: 103: 104: private:
105: //用于存储比特位的数组
106: WORD *start, *end;107: //字的数目
108: size_t szWord; 109: 110: //utility function
111: //设置refWord的第pos位为1
112: inline void pvSet(WORD& refWord, size_t pos)
113: { 114: WORD tmp = 0x80000000 >> pos; 115: refWord |= tmp; 116: } 117: 118: //设置refWord的第pos位为0
119: inline void pvReset(WORD& refWord , size_t pos)
120: { 121: WORD tmp = ~(0x80000000 >> pos); 122: refWord &= tmp; 123: } 124: 125: //统计refWord中1的个数
126: size_t count_bit_1(const WORD& refWord)const
127: { 128: WORD tmp = refWord ; 129: size_t cnt = 0;130: while(tmp > 0)
131: { 132: tmp &= tmp-1; 133: ++cnt; 134: } 135: 136: return cnt;
137: } 138: 139: //侦测pWord数组中有无被置为1的位
140: bool testArrayAny(const WORD*pWord, size_t arraySize, size_t bitcount)const
141: {142: for(const WORD* pw = pWord; pw < pWord + arraySize; ++pw)
143: {144: if (*(pw))
145: return true;
146: } 147: 148: return false;
149: } 150: 151: //字符串转为字
152: void string_to_words(const string&str)
153: { 154: size_t len = str.length(), i; 155: WORD *pw = start; 156: 157: for(i = 0; i + WORD_LEN < len; i += WORD_LEN, ++pw)
158: {159: string subStr = str.substr(i , WORD_LEN);
160: *pw = 0;161: for(int j = 0; j < WORD_LEN; ++j)
162: {163: if(subStr[j] == '1')
164: { 165: *pw |= 0x80000000 >> j; 166: } 167: } 168: } 169: 170: string left = str.substr(i, len - i);
171: for(int j = 0; j + i < len; ++j)
172: {173: if(left[j] == '1')
174: { 175: *pw |= 0x80000000 >> j; 176: } 177: } 178: } 179: 180: //把字转为字符串
181: string bitset::word_to_string(const WORD& refWord )const
182: {183: /*
184: static char*table[] = {"0000", "0001", "0010", "0011",
185: "0100", "0101", "0110", "0111",
186: "1000", "1001", "1010", "1011",
187: "1100", "1101", "1110", "1111"};
188: string str;
189: WORD tmp1, tmp2;
190: 191: for(size_t i = 0; i < WORD_LEN / 4; ++i)
192: {
193: tmp2 = (0xF0000000>>(4*i));
194: tmp1 = refWord & tmp2;
195: tmp1 >>= (WORD_LEN - 4 - 4*i);
196: str += table[tmp1];
197: }
198: 199: return str;
200: */
201: /*the below method is simpler, but its performance is not explicitly better or worse than
202: the above method*/
203: string str("00000000000000000000000000000000");
204: for(int i = 0; i < WORD_LEN ; ++i)
205: { 206: WORD tmp = 1 << i;207: str[i] = (refWord & tmp)? '1':'0';
208: } 209: 210: return str;
211: } 212: 213: //反转src
214: WORD reverse_word(const WORD&src)const
215: { 216: WORD result = 0;217: for(int i = 0; i < WORD_LEN; ++i)
218: {219: if((1<<i) & src)
220: { 221: result |= 0x80000000 >> i; 222: } 223: } 224: 225: return result;
226: } 227: 228: //创建一个bitset
229: void create()
230: { 231: szWord = BITSET_WORD_CNT(sz);232: start = new WORD[szWord];
233: end = start + szWord; 234: 235: reset(); 236: } 237: 238: //clear the redundant bits of the last word
239: void clear()
240: { 241: size_t left = sz - WORD_LEN * (szWord-1); 242: WORD tmp = ~(0xFFFFFFFF >> left); 243: *(end-1) &= tmp; 244: } 245: 246: public:
247: //Type defines
248: typedef bitset& reference;249: typedef const bitset& const_reference;
250: 251: //默认构造函数
252: bitset() 253: { 254: create(); 255: } 256: 257: //用整数构造
258: bitset(unsigned long n)
259: { 260: create(); 261: *start = reverse_word(n); 262: //clear the redundant bits of the last word
263: clear(); 264: } 265: 266: //用字符串构造
267: bitset(string binarySeq)
268: {269: if(binarySeq.empty())
270: { 271: create();272: return;
273: } 274: 275: if(binarySeq.length() >= sz)
276: { 277: binarySeq = binarySeq.substr(0, sz); 278: } 279: 280: //翻转二进制序列
281: reverse(binarySeq.begin(), binarySeq.end()); 282: 283: create(); 284: 285: string_to_words(binarySeq); 286: } 287: 288: //复制构造函数
289: bitset(const bitset<sz>& rhs)
290: { 291: create();292: for(WORD* pw = start, *pwRhs = rhs.start; pw < end; ++pw, ++pwRhs)
293: { 294: *pw = *pwRhs; 295: } 296: } 297: 298: //赋值操作符
299: bitset<sz>& operator = (const bitset<sz>&rhs)
300: {301: for(WORD* pw = start, *pwRhs = rhs.start; pw < end; ++pw, ++pwRhs)
302: { 303: *pw = *pwRhs; 304: } 305: 306: return *this;
307: } 308: 309: //析构函数
310: ~bitset() 311: { 312: delete []start; 313: start = 0; 314: } 315: 316: //重置所有位为1
317: inline void set()
318: {319: memset(start, -1, sizeof(WORD)*szWord);
320: clear(); 321: } 322: 323: //重置pos位为1
324: void set(size_t pos)
325: { 326: #ifdef EXCEPTION_HANDLE327: if(pos >= sz)
328: throw data_error();
329: #endif
330: 331: if(!test(pos))
332: { 333: size_t wordpos = pos / WORD_LEN; 334: size_t ofstInWord = pos % WORD_LEN; 335: 336: pvSet(*(start + wordpos ), ofstInWord ); 337: } 338: } 339: 340: //重置所有位为0
341: inline void reset()
342: {343: memset(start , 0 , sizeof(WORD)*szWord);
344: } 345: 346: //重置pos位为0
347: void reset(size_t pos)
348: { 349: #ifdef EXCEPTION_HANDLE350: if(pos >= sz)
351: throw data_error();
352: #endif
353: if(test(pos))
354: { 355: size_t wordpos = pos / WORD_LEN; 356: size_t ofstInWord = pos % WORD_LEN; 357: pvReset(*(start + wordpos ), ofstInWord ); 358: } 359: } 360: 361: //翻转所有位
362: void flip()
363: {364: for(WORD*pw = start; pw < end; ++pw)
365: *(pw) = ~(*(pw)); 366: } 367: 368: //翻转pos位
369: void flip(size_t pos)
370: { 371: #ifdef EXCEPTION_HANDLE372: if(pos >= sz)
373: throw data_error();
374: #endif
375: 376: size_t wordpos = pos / WORD_LEN; 377: size_t ofstInWord = pos % WORD_LEN; 378: WORD tmp = ~(*(start + wordpos)); 379: pvSet (tmp, ofstInWord ); 380: 381: *(start + wordpos) ^= tmp; 382: } 383: 384: //测试pos位
385: bool test(size_t pos)const
386: { 387: #ifdef EXCEPTION_HANDLE388: if(pos >= sz)
389: throw data_error();
390: #endif
391: 392: size_t wordpos = pos / WORD_LEN; 393: size_t ofstInWord = pos % WORD_LEN; 394: WORD tmp = 0x80000000 >> ofstInWord ; 395: 396: if((*start + wordpos) & tmp)
397: return true;
398: return false;
399: } 400: 401: //测试有没有被置为1的位
402: bool any()const
403: {404: return testArrayAny(start, szWord, sz);
405: } 406: 407: //测试是否全为0
408: bool none()const
409: {410: return !any();
411: } 412: 413: //返回1的个数
414: size_t count() 415: { 416: size_t bitCnt = 0;417: for (WORD*pw = start; pw < end; ++pw)
418: { 419: bitCnt += count_bit_1(*pw); 420: } 421: 422: return bitCnt ;
423: } 424: 425: //转为字符串表示
426: string to_string()const
427: {428: string str;
429: size_t lastwordleft = (sz + WORD_LEN - 1) % WORD_LEN + 1; 430: 431: for (WORD* pw = end; pw > start;--pw)
432: { 433: str += word_to_string(*(pw-1)); 434: } 435: 436: str = str.substr(WORD_LEN - lastwordleft, str.length() - (WORD_LEN - lastwordleft)); 437: 438: return str;
439: } 440: 441: //转为unsigned long
442: unsigned long to_ulong()const
443: { 444: #ifdef EXCEPTION_HANDLE445: if(testArrayAny(start+1, szWord-1, sz - WORD_LEN))
446: throw data_error("This bitset cannot convert to unsigned long type value");
447: #endif
448: return static_cast<unsigned long>( reverse_word(start[0]) );
449: } 450: 451: //bitset大小
452: inline size_t size()const
453: {454: return sz;
455: } 456: 457: //Operators
458: 459: bit operator [](size_t pos)const
460: { 461: #ifdef EXCEPTION_HANDLE462: if(pos >= sz)
463: throw data_error();
464: #endif
465: 466: bit dummy(*this, pos);
467: return dummy;
468: } 469: 470: bit operator [](size_t pos)
471: { 472: #ifdef EXCEPTION_HANDLE473: if(pos >= sz)
474: throw data_error();
475: #endif
476: 477: bit dummy(*this, pos);
478: return dummy;
479: } 480: 481: //logic operators
482: bool operator == (const bitset<sz>& rhs)const
483: { 484: #ifdef EXCEPTION_HANDLE485: if(size() != rhs.size())
486: return false;
487: #endif
488: 489: for(WORD *pw = start, *pwRhs = rhs.start; pw < end; ++pw, ++pwRhs)
490: {491: if(*pw != *pwRhs)
492: return false;
493: } 494: 495: return true;
496: } 497: 498: bool operator != (const bitset<sz>& rhs)const
499: {500: return !(*this == rhs);
501: } 502: 503: bool operator < (const bitset<sz>& rhs)const
504: {505: return to_string() < rhs.to_string();
506: } 507: 508: bool operator <= (const bitset<sz>& rhs)const
509: {510: return (*this < rhs) || (*this == rhs);
511: } 512: 513: bool operator > (const bitset<sz>& rhs)const
514: {515: return !(*this <= rhs);
516: } 517: 518: bool operator >=(const bitset<sz>& rhs)const
519: {520: return !(*this < rhs);
521: } 522: 523: //bit operators
524: bitset<sz> operator &(const bitset<sz>& rhs)const
525: { 526: bitset<sz> retbt;527: for(WORD *pw = start, *pwRhs = rhs.start, *pwRet = retbt.start; pw < end; ++pw, ++pwRhs, ++pwRet)
528: { 529: *pwRet = (*pw) & (*pwRhs); 530: }531: return retbt;
532: } 533: 534: bitset<sz>& operator &=(const bitset<sz>& rhs)
535: {536: for(WORD *pw = start, *pwRhs = rhs.start; pw < end; ++pw, ++pwRhs)
537: { 538: *pw &= *pwRhs; 539: } 540: } 541: 542: bitset<sz> operator |(const bitset<sz>& rhs)const
543: { 544: bitset<sz> retbt;545: for(WORD *pw = start, *pwRhs = rhs.start, *pwRet = retbt.start; pw < end; ++pw, ++pwRhs, ++pwRet)
546: { 547: *pwRet = (*pw) | (*pwRhs); 548: }549: return retbt;
550: } 551: 552: bitset<sz>& operator |=(const bitset<sz>& rhs)
553: {554: for(WORD *pw = start, *pwRhs = rhs.start; pw < end; ++pw, ++pwRhs)
555: { 556: *pw |= *pwRhs; 557: } 558: 559: return *this;
560: } 561: 562: bitset<sz> operator ^(const bitset<sz>& rhs)const
563: { 564: bitset<sz> retbt;565: for(WORD *pw = start, *pwRhs = rhs.start, *pwRet = retbt.start; pw < end; ++pw, ++pwRhs, ++pwRet)
566: { 567: *pwRet = (*pw) ^ (*pwRhs); 568: } 569: 570: return retbt;
571: } 572: 573: bitset<sz>& operator ^=(const bitset<sz>& rhs)
574: {575: for(WORD *pw = start, *pwRhs = rhs.start; pw < end; ++pw, ++pwRhs)
576: { 577: *pw ^= *pwRhs; 578: } 579: 580: return *this;
581: } 582: 583: bitset<sz> operator ~()const
584: { 585: bitset<sz> retbt; 586: 587: for(WORD* pw = start, *pwRet = retbt.start; pw < end; ++pw, ++pwRet)
588: { 589: *pwRet = ~(*pw); 590: } 591: 592: retbt.clear(); 593: 594: return retbt;
595: } 596: 597: bitset<sz> operator >>(size_t offset)
598: { 599: size_t size = sz; 600: bitset<sz> retbt; 601: 602: if(offset >= sz)
603: {604: return retbt;
605: } 606: 607: size_t firstOffset, secondOffset, firstShift, secondShift;; 608: firstOffset = offset / WORD_LEN; 609: secondOffset = (offset + WORD_LEN - 1) / WORD_LEN; 610: firstShift = offset % WORD_LEN; 611: secondShift = WORD_LEN - firstShift; 612: 613: WORD *first, *second, *pwRet; 614: first = start + firstOffset; 615: second = start + secondOffset; 616: pwRet = retbt.start; 617: 618: while (first < end)
619: { 620: WORD tmp1 = *first++ << firstShift, 621: tmp2 = second < end ?(*second++ >> secondShift) : 0; 622: *pwRet++ = tmp1 | tmp2; 623: } 624: 625: return retbt;
626: } 627: 628: bitset<sz>& operator >>=(size_t offset)
629: { 630: size_t size = sz; 631: 632: //See if beyond the limit
633: if(offset >= size)
634: {635: this->reset();
636: return *this;
637: } 638: 639: size_t firstOffset, secondOffset, firstShift, secondShift;; 640: firstOffset = offset / WORD_LEN; 641: secondOffset = (offset + WORD_LEN - 1) / WORD_LEN; 642: firstShift = offset % WORD_LEN; 643: secondShift = WORD_LEN - firstShift; 644: 645: WORD *first, *second, *pw; 646: first = start + firstOffset; 647: second = start + secondOffset; 648: pw = start;649: while (first < end)
650: { 651: WORD tmp1 = (*first++ << firstShift), 652: tmp2 = second < end ?(*second++ >> secondShift) : 0; 653: *pw++ = tmp1 | tmp2; 654: } 655: 656: while(pw < end)
657: { 658: *pw++ = 0; 659: } 660: 661: return *this;
662: } 663: 664: //这段代码的算法相对复杂,故而略去注释
665: bitset<sz> operator <<(size_t offset)
666: { 667: size_t size = sz; 668: bitset<sz> retbt; 669: 670: if(offset >= size)
671: {672: return retbt;
673: } 674: 675: size_t firstOffset, secondOffset, firstShift, secondShift;; 676: firstOffset = offset / WORD_LEN; 677: secondOffset = (offset + WORD_LEN - 1) / WORD_LEN; 678: firstShift = offset % WORD_LEN; 679: secondShift = WORD_LEN - firstShift; 680: 681: WORD *first, *second, *pwRet; 682: first = end - firstOffset; 683: second = end - secondOffset; 684: pwRet = retbt.end; 685: 686: while(first > start)
687: { 688: WORD tmp1 = *(first-- - 1) >> firstShift, 689: tmp2 = second > start? (*(second-- - 1) << secondShift) : 0; 690: *(pwRet-- - 1) = tmp1 | tmp2; 691: } 692: 693: return retbt;
694: } 695: 696: bitset<sz>& operator <<=(size_t offset)
697: { 698: size_t size = sz; 699: 700: if(offset >= size)
701: {702: this->reset();
703: return *this;
704: } 705: 706: //Move right, because the order is opposite
707: size_t firstOffset, secondOffset, firstShift, secondShift;; 708: firstOffset = offset / WORD_LEN; 709: secondOffset = (offset + WORD_LEN - 1) / WORD_LEN; 710: firstShift = offset % WORD_LEN; 711: secondShift = WORD_LEN - firstShift; 712: 713: WORD *first, *second, *pw; 714: first = end - firstOffset; 715: second = end - secondOffset; 716: pw = end; 717: 718: while(first > start)
719: { 720: WORD tmp1 = *(first-- - 1) >> firstShift, 721: tmp2 = second > start? (*(second-- - 1) << secondShift) : 0; 722: *(pw-- - 1) = tmp1 | tmp2; 723: } 724: 725: while(pw > start)
726: { 727: *(pw-- - 1) = 0; 728: } 729: 730: return *this;
731: } 732: 733: 734: }; 735: 736: 737: //输出操作符重载
738: template<int sz>
739: ostream& operator <<(ostream&os, bitset<sz>bs)
740: {741: return os<<bs.to_string();
742: } 743: } 744: 745: #endif
219

被折叠的 条评论
为什么被折叠?



