bitset实现(转)

感觉bitset实现很漂亮--所以转载

转自:http://blog.sina.com.cn.sixxs.org/u/1282003632

感谢原作者!

为了区分C++标准库中的bitset数据结构,在本程序中使用_bitset。
如果设置_bitset的长度为4,则可操作的位为0-3。
//_bitset.h
#ifndef _BITSET_H
#define _BITSET_H
#include <limits>
#include <cstring>
#include <iostream>
using namespace std;
class _bitset
{
 friend ostream & operator << (ostream & out,const _bitset & elem);   //重载输出操作符
public:
 typedef unsigned long block_type;   //最小存储单元块的类型
 typedef unsigned long size_type;    //最小存储单元块的大小类型
private:
 enum {BLOCK_BYTES = sizeof(block_type)};     //最小存储单元块的字节数
 enum {BLOCK_BITS = std::numeric_limits<block_type>::digits};  //最小单元存储块的位数,平台通用性,所以使用numeric_limits
public:
 _bitset();
 _bitset(size_type val);
 _bitset(const _bitset & val);
 _bitset & operator=(const _bitset & val);
 ~_bitset();
 _bitset & operator <<= (size_type num);  //左移赋值操作
 _bitset & operator >>= (size_type num);  //右移赋值操作
 _bitset & set(size_type pos,bool tagSet = true); //设置bitset中的某一位的值
 _bitset & clear(bool tagClear = true);    //使得bitset中每一位都为0
 _bitset & flip();       //反转所有位操作
 _bitset & operator ~();      //取反操作符
 _bitset & flip(size_type pos);    //反转pos位的操作
 bool test(size_type pos) const;    //测试相应位是1还是0
 _bitset & operator &= (const _bitset & val);
 _bitset & operator |= (const _bitset & val);
 _bitset & operator ^= (const _bitset & val);
 bool operator == (const _bitset & val) const;
 size_type size() const;
private:
 void leftShift(size_type num);   //左移操作
 void rightShift(size_type num);   //右移操作
private:
 size_type m_bitNum;   //bitset中位的个数
 size_type m_size;     //block_type的个数
 block_type * m_pBits; //存储bit位
 block_type m_mask;    //假如bitset的位数是5,而m_pBits[0]=0xFFFFFFFF,m_mask用来表示
                       //m_pBits[0]的后5位有效
};
_bitset operator << (const _bitset &,_bitset::size_type);
_bitset operator >> (const _bitset &,_bitset::size_type);
_bitset operator & (const _bitset &,const _bitset &);
_bitset operator | (const _bitset &,const _bitset &);
_bitset operator ^ (const _bitset &,const _bitset &);
inline _bitset::_bitset(size_type bitNum)
{
 m_bitNum = bitNum;
 size_type free_bits = (BLOCK_BITS - m_bitNum % BLOCK_BITS) % BLOCK_BITS;
 m_size = m_bitNum / BLOCK_BITS + (free_bits == 0 ? 0 : 1);
 m_pBits = new block_type[m_size];
 if (m_pBits == NULL)
 {
  cout << "no enough memorry!\n";
  exit(0);
 }
 clear();
 m_mask = ~block_type(0);
 m_mask >>= free_bits;
}
inline _bitset::_bitset(const _bitset &val)
{
 m_size = val.m_size;
 m_pBits = new block_type[m_size];
 if (m_pBits == NULL)
 {
  cout << "no enough memorry!\n";
  exit(0);
 }
 memcpy(m_pBits,val.m_pBits,m_size * BLOCK_BYTES);
 m_bitNum = val.m_bitNum;
 m_mask = val.m_mask;
}
inline _bitset & _bitset::operator =(const _bitset &val)
{
 if (this == &val)
  return (*this);
 if (m_size != val.m_size)
 {
  delete [] m_pBits;
  m_size = val.m_size;
  m_pBits = new block_type[m_size];
  if (m_pBits == NULL)
  {
   cout << "no enough memorry!\n";
   exit(0);
  }
 }
 memcpy(m_pBits,val.m_pBits,m_size * BLOCK_BYTES);
 m_bitNum = val.m_bitNum;
 m_mask = val.m_mask;
 return (*this);
}
inline _bitset::~_bitset()
{
 delete [] m_pBits;
}
inline _bitset & _bitset::operator <<=(_bitset::size_type num)
{
 leftShift(num);
 return (*this);
}
inline _bitset & _bitset::operator >>=(_bitset::size_type num)
{
 rightShift(num);
 return (*this);
}
inline _bitset::size_type _bitset::size() const
{
 return m_bitNum;
}
inline _bitset & _bitset::flip()
{
 for (size_type i=0;i<m_size;++i)
  m_pBits[i] = ~m_pBits[i];
 m_pBits[m_size-1] &= m_mask;
 return (*this);
}
inline _bitset & _bitset::operator~()
{
 return _bitset(*this).flip();
}
inline _bitset & _bitset::operator &=(const _bitset &val)
{
 if (m_bitNum != val.m_bitNum)
 {
  cout << "different length\n";
  exit(0);
 }
 for (size_type i=0;i<m_size;i++)
  m_pBits[i] &= val.m_pBits[i];
 return (*this);
}
inline _bitset & _bitset::operator |=(const _bitset &val)
{
 if (m_bitNum != val.m_bitNum)
 {
  cout << "different length\n";
  exit(0);
 }
 for (size_type i=0;i<m_size;i++)
  m_pBits[i] |= val.m_pBits[i];
 return (*this);
}
inline _bitset & _bitset::operator ^=(const _bitset &val)
{
 if (m_bitNum != val.m_bitNum)
 {
  cout << "different length\n";
  exit(0);
 }
 for (size_type i=0;i<m_size;i++)
  m_pBits[i] ^= val.m_pBits[i];
 return (*this);
}
inline bool _bitset::operator ==(const _bitset &val) const
{
 if (m_bitNum != val.m_bitNum)
  return false;
 for (size_type i=0;i < m_size;++i)
  if (m_pBits[i] != val.m_pBits[i])
   return false;
 return true;
}
inline _bitset operator << (const _bitset & val,_bitset::size_type num)
{
 return _bitset(val) <<= num;
}
inline _bitset operator >> (const _bitset & val,_bitset::size_type num)
{
 return _bitset(val) >>= num;
}
inline _bitset operator | (const _bitset & l,const _bitset & r)
{
 return _bitset(l) |= r;
}
inline _bitset operator & (const _bitset & l,const _bitset & r)
{
 return _bitset(l) &= r;
}
inline _bitset operator ^ (const _bitset & l,const _bitset & r)
{
 return _bitset(l) ^= r;
}
inline _bitset & _bitset::clear(bool tagClear)
{
 if (tagClear)
 {
  memset(m_pBits,0,m_size * BLOCK_BYTES);
 }
 else
 {
  memset(m_pBits,std::numeric_limits<unsigned char>::max(),m_size * BLOCK_BYTES);
  m_pBits[m_size-1] &= m_mask;
 }
 return (*this);
}
#endif
 
//_bitset.cpp
#include "_bitset.h"
void _bitset::leftShift(_bitset::size_type num)
{
 if (num >= m_bitNum)
 {
  clear();
  return;
 }
 size_type eleNum = num / BLOCK_BITS;
 size_type bitNum = num % BLOCK_BITS;
 if (eleNum != 0)
 {
  block_type * pTmp = new block_type[m_size];
  if (pTmp == NULL)
  {
   cout << "no enough memory\n";
   exit(0);
  }
  memcpy(pTmp,m_pBits,(m_size-eleNum)*BLOCK_BYTES);
  memcpy(m_pBits+eleNum,pTmp,(m_size-eleNum)*BLOCK_BYTES);
  memset(m_pBits,0,eleNum*BLOCK_BYTES);
  delete [] pTmp;
 }
 if (bitNum != 0)
 {
  block_type * pTmp = m_pBits + m_size -1;
  for (;pTmp > m_pBits;--pTmp)
  {
   *pTmp = (*pTmp << bitNum) | (*(pTmp-1) >> (BLOCK_BITS - bitNum)); //*pTmp的地位或上(*(pTmp-1))的高位
  }
  *pTmp <<= bitNum;
 }
 m_pBits[m_size-1] &= m_mask;  //将数组最高位的元素无用位置0
}
void _bitset::rightShift(_bitset::size_type num)
{
 if (num >= m_bitNum)
 {
  clear();
  return;
 }
 size_type eleNum = num / BLOCK_BITS;
 size_type bitNum = num % BLOCK_BITS;
 if (eleNum != 0)
 {
  block_type * pTmp = new block_type[m_size];
  if (pTmp == NULL)
  {
   cout << "no enough memory\n";
   exit(0);
  }
  memcpy(pTmp,m_pBits+eleNum,(m_size-eleNum)*BLOCK_BYTES);
  memcpy(m_pBits,pTmp,(m_size-eleNum)*BLOCK_BYTES);
  memset(m_pBits+m_size-eleNum,0,eleNum * BLOCK_BYTES);
  delete [] pTmp;
 }
 if (bitNum != 0)
 {
  block_type * pTmp = m_pBits;
  for (;pTmp < m_pBits + m_size -1;++pTmp)
  {
   *pTmp = (*pTmp >> bitNum) | (*(pTmp+1) << (BLOCK_BITS - bitNum));
  }
  *pTmp >>= bitNum;
 }
}
_bitset & _bitset::set(size_type pos,bool tagSet)
{
 if (pos > m_bitNum || pos < 0)
 {
  cout << "position is not right\n";
  exit(0);
 }
 
 size_type eleNum = pos / BLOCK_BITS;
 size_type bitNum = pos % BLOCK_BITS;
 block_type mask = 1;
 mask <<= bitNum;
 if (tagSet)
 {
  m_pBits[eleNum] |= mask;
 }
 else
 {
  m_pBits[eleNum] &= ~mask;
 }
 return (*this);
}
_bitset & _bitset::flip(_bitset::size_type pos)
{
 if (pos > m_bitNum || pos < 0)
 {
  cout << "position is not right\n";
  exit(0);
 }
 
 size_type eleNum = pos / BLOCK_BITS;
 size_type bitNum = pos % BLOCK_BITS;
 block_type mask = 1;
 mask <<= bitNum;
 m_pBits[eleNum] = m_pBits[eleNum] ^ mask;
 return (*this);
}
bool _bitset::test(_bitset::size_type pos) const
{
 if (pos > m_bitNum || pos < 0)
 {
  cout << "position is not right\n";
  exit(0);
 }
 
 size_type eleNum = pos / BLOCK_BITS;
 size_type bitNum = pos % BLOCK_BITS;
 block_type mask = 1;
 mask <<= bitNum;
 return m_pBits[eleNum] & mask;
}
ostream & operator << (ostream & out,const _bitset & elem)
{
 _bitset::size_type j = 0;
 _bitset::size_type mask = 1;
 mask <<= (elem.m_bitNum % _bitset::BLOCK_BITS-1);
 for (_bitset::size_type i = elem.m_bitNum-1;i>0;i--)
 {
  if (i % (_bitset::BLOCK_BITS) == 0)
  {
   j++;
   mask = 1;
   mask <<= (_bitset::BLOCK_BITS-1);
  }
  if (elem.m_pBits[elem.m_size-j-1] & mask)
  {
   out << 1;
  }
  else
  {
   out << 0;
  }
  mask >>= 1;
 }
 return out;
}
 
//main 测试函数
#include <iostream>
#include <bitset>
#include <limits>
#include "_bitset.h"
using namespace std;
int main()
{
 bitset<4> mybits;
 //cout << mybits << endl;
 cout << mybits.set(3) << endl;
 _bitset bit(34);
 bit.set(33);
 //bit.rightShift(1);
 //bit <<= 1;
 cout << bit << endl;
}

bitset数据结构能够有效的节约存储空间,在海量数据排序,海量数据检索中都有用处。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值