位操作类

在标准C++中,C++中的位操作类(Bitset)提供一个位集合的数据结构。利用这个结构,可以实现某些很复杂的功能,比如权限设计、游戏中的存档,成绩是否及格等。这个结构的一个优点是能够节省空间(尤其在网络传输的时候,优点就体现出来了),这里模仿<Data Structure for game programers>写了一个类似的位操作类,主要采用长整型数来保存位,两个长整型就能保存64个位,主要的操作还是位操作(以为、与、并、异或等等)。

 类的设计与定义如下:

//  文件摘要:通用位数组类
//  文件标识:BitVector.h
//  创建日期:2010-10-29
//  ============================================================================
#ifndef BITVECTOR_H
#define  BITVECTOR_H

#include 
< iostream >
#include 
< cstdio >

class  BitVector
{
public :
    
// 摘要:构造函数
    
// 参数:pSize-位数
    BitVector(size_t pSize  =  INIT_SIZE):elems( 0 ),size(pSize)
    {
        size_t nums 
=   0 ;
        
if (size  %   32   ==   0 )
        {
            size 
=  size  /   32
        }
        
else
        {
            size 
=  size  /   32   +   1 ;
        }
        elems 
=   new  unsigned  long   int [size];
    }

    
// 析构函数
     ~ BitVector()
    {
        
if (elems  !=   0 )
            delete[] elems;
        elems 
=   0 ;
    }

    
// 摘要:改变大小成员函数
    
// 参数:pSize-位数
     void  Resize(size_t pSize);

    
// 摘要:下标操作符,取得所在位的值
    
// 参数:位所在位置
    
// 返回:true 或者 false
     bool   operator [](size_t pIndex);

    
// 摘要:设置某位为特定值(0或者1)
    
// 参数:pIndex - 索引位位置 , pValue - 待设置的值
     void  Set(size_t pIndex ,  bool  pValue);

    
// 摘要:全部清零操作
     void  ClearAll();

    
// 摘要:全部置位操作(其实可以采用默认参数,如果不传特定值,默认全部置位)
     void  SetAll();

    
// 摘要:写二进制文件
    
// 参数:path-文件保存路径
    
// 返回:成功返回true否则返回false
     bool  WriteToFile( const   char   * path);

    
// 摘要:读二进制文件
    
// 参数:path-文件路径
    
// 返回:成功返回true否则返回false
     bool  ReadFromFile( const   char   * path);

    
// 摘要:输出所有的长整型表示的数,以及二进制表示形式
     void  ToString() 
    {
        
for (size_t index  =   0 ; index  <  size ;  ++ index)
        {
            std::cout 
<<   " 长整型数值为: "   <<  std::dec  <<  elems[index]  <<   "  二进制表示为: "   <<  std::hex  <<  elems[index]  <<  std::endl;
        }
    }
private :
    
static   const   int  INIT_SIZE  =   32 ;
    unsigned 
long   int   * elems;   // 长整型数组
    size_t size;                // 长整型数目,据此可求出可表达的位数为:size*32;
};

inline 
void  BitVector::Resize(size_t pSize)
{
    
// 定义新空间
    unsigned  long   int   * newVector  =   0 ;

    
// 求出整形数目
     if (pSize  %   32   ==   0 )
    {
        size 
=  size  /   32 ;
    }
    
else
    {
        size 
=  (size  /   32 +   1 ;
    }

    
// 分配新空间
    newVector  =   new  unsigned  long   int [size];

    
// 分配失败,退出
     if (newVector  ==   0 )
        
return ;

    
// 取小值
    size_t min  =  size  <  pSize  ?  size : pSize;

    
// 复制
     for (size_t index  =   0  ; index  <  min;  ++ index)
    {
        newVector[index] 
=  elems[index];
    }

    
// 保存新值
    size  =  pSize;

    
// 删除旧空间
     if (elems  !=   0 )
        delete[] elems;

    
// 保存新地址
    elems  =  newVector;
}

inline 
bool  BitVector:: operator [](size_t pIndex)
{
    size_t cell 
=  pIndex  /   32 ;
    size_t bit 
=  pIndex  %   32 ;
    
return  (elems[cell]  &  ( 1   <<  bit))  >>  bit;
}

inline 
void  BitVector::Set(size_t pIndex ,  bool  pValue)
{
    
// 找出所在单元和具体位置
    size_t cell  =  pIndex  /   32 ;
    size_t bit 
=  pIndex  %   32 ;

    
// 如果设置true
     if (pValue)
    {
        elems[cell] 
=  (elems[cell]  |  ( 1 << bit));
    }
    
// 如果设置为false
     else
    {
        elems[cell] 
=  (elems[cell]  &  ( ~ ( 1 << bit)));
    }
}

inline 
void  BitVector::ClearAll()
{
    
for (size_t index  =   0  ; index  <  size;  ++ index)
    {
        elems[index] 
=   0 ;
    }
}

inline 
void  BitVector::SetAll()
{
    
for (size_t index  =   0 ; index  <  size;  ++ index)
    {
        elems[index] 
=   0xFFFFFFFF ;
    }
}

inline 
bool  BitVector::WriteToFile( const   char   * path)
{
    std::FILE 
* outFile  =   0 ;
    
int  written  =   0 ;
    outFile 
=  std::fopen(path, " wb " );
    
    
// 打开文件失败
     if (outFile  ==   0 )
    {
        
return   false ;
    }

    
// 写文件,同时返回写入的对象个数
    written  =  std::fwrite(elems, sizeof ( * elems),size,outFile);

    
// 关闭文件流
    std::fclose(outFile);
    
    
// 检测写入的个数
     if (written  !=  size)
    {
        
return   false ;
    }

    
return   true ;
}

inline 
bool  BitVector::ReadFromFile( const   char   * path)
{
    std::FILE 
* inFile  =   0 ;
    
int  read  =   0 ;
    inFile 
=  std::fopen(path, " rb " );
    
if (inFile  ==   0 )
        
return   false ;

    
// 读文件,返回读入的对象个数
    read  =  std::fread(elems, sizeof (unsigned  long   int ),size,inFile);

    
// 关闭文件
    std::fclose(inFile);

    
if (read  !=  size)
        
return   false ;

    
return   true ;
}
#endif 

 

//测试代码如下: 


#include 
< iostream >
#include 
< tchar.h >
#include 
< string >
#include 
< cstdlib >
#include 
< cstring >
#include 
< ctime >
#include 
< sys / timeb.h >

#include 
" BitVector.h "
using   namespace  std;

int  _tmain( int  argc, _TCHAR *  argv[])
{
  
    
// 一个长整形表示32个位值(随机数)
    BitVector bitv( 32 );
    bitv.ToString();

    
// 设置所有位为1,同 bitv.SetAll()
     for ( int  i = 0 ;i < 32 ;i ++ )
    {
        bitv.Set(i,
true );
    }
    bitv.ToString();

    
// 设置第三位为0,于是最后变为1011(十六进制的b)
    bitv.Set( 2 , 0 );
    bitv.ToString();

    
// 写文件
    bitv.WriteToFile( " bitv.py " );

    
// 读文件
    bitv.ReadFromFile( " bitv.py " );

    
// 位全部设置为0
    bitv.ClearAll();
    bitv.ToString();

    system(
" pause " );
    
return   0 ;
}

 

 

你可能感兴趣的:(位操作)