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