位操作类

在标准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;
}

 

 

posted on 2010-10-29 17:18  虚怀若谷  阅读(351)  评论(0编辑  收藏  举报

导航