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数据结构能够有效的节约存储空间,在海量数据排序,海量数据检索中都有用处。