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

 

posted @ 2015-06-30 19:47  balingybj  阅读(1358)  评论(0编辑  收藏  举报