其实c++里有bitset这个类,但是bitset使用时必须给定大小。例如
bitset<8> c;//这里必须在编码里写死,不能使用变量替代
c = 234;
我主要是用这个东西来存储可变长的huffman编码。所以这个类对我根本不能用。除非开始就给一个足够大的bitset。
所以我创建里一个可变长的bit vector用于存放Huffman编码。
在这里内部使用的是__int64,64位。当然根据实际需要可以将这个做为模板传入,不过现在还没有这样编码。
- /* created by chico chen
- * date 2008/10/25
- */
- #ifndef _BIT_VECTOR_
- #define _BIT_VECTOR_
- #include <iostream>
- using namespace std;
- class BITVector
- {
- private:
- __int64 * bitarray;
- const int bits;
- const unsigned __int64 mask ;
- int size;
- void SetOne(int index);// x is 0
- void SetZero(int index);// x is 1
- void Larger();
- public:
- BITVector(void);
- void Set(int index, int x); // x is 0 or 1
- int Get(int index);
- int Size();
- void SetInt(unsigned int integer,int start,int len);
- void PrintfZeroOne(int start , int len);// print the unsigned it as 0 or 1
- void SetBitVector(BITVector & c, int start, int len);
- const BITVector& operator=(const BITVector& bitVector);
- explicit BITVector(const BITVector & bitVector);
- public:
- ~BITVector(void);
- };
- #endif
然后是bitVector.cpp文件
- /* created by chico chen
- * date 2008/10/25
- */
- #include "StdAfx.h"
- #include "BITVector.h"
- BITVector::BITVector(void):mask(0x8000000000000000),bits(sizeof(__int64)*8)
- {
- bitarray = new __int64[1];
- memset(bitarray,0,sizeof(__int64));
- size = 1;
- }
- BITVector::~BITVector(void)
- {
- size = 0;
- delete[] bitarray;
- }
- void BITVector::Set(int index, int x)
- {
- if(x == 0)
- {
- return SetZero(index);
- }
- else
- {
- return SetOne(index);
- }
- }
- void BITVector::SetZero(int index)
- {
- int innIndex = index/bits;
- int bitPos = index & (bits-1); // innIndex % 8
- if( innIndex < size)
- {
- // vector maybe has enough space to store this .
- this->bitarray[innIndex] = this->bitarray[innIndex] & ~(mask >> bitPos);
- }
- else if(innIndex == size)
- {
- // should larger the size of bitarray
- // and innIndex must be the first bit of last char
- if(bitPos == 0)
- {
- // correct
- this->Larger();
- this->bitarray[innIndex] = this->bitarray[innIndex] & ~(mask >> bitPos);
- }
- else
- {
- // error
- }
- }
- else
- {
- // there may be something error, or some code missing
- }
- }
- void BITVector::Larger()
- {
- __int64 * tempArray = new __int64[size];
- memcpy(tempArray,this->bitarray,sizeof(__int64)*size);
- delete[] this->bitarray;
- this->bitarray = new __int64[size*2]; // may be error
- memset(bitarray,0,sizeof(__int64)*size*2);
- memcpy(this->bitarray,tempArray,sizeof(__int64)*size);
- size = size*2;
- delete[] tempArray;
- }
- void BITVector::SetOne(int index)
- {
- int innIndex = index/bits; // you can use >>(bits-1)
- int bitPos = index % bits; // innIndex & (bits-1)
- if( innIndex < size)
- {
- // vector maybe has enough space to store this .
- this->bitarray[innIndex] = this->bitarray[innIndex] | (mask >> bitPos);
- }
- else if(innIndex == size)
- {
- // should larger the size of bitarray
- // and innIndex must be the first bit of last char
- if(bitPos == 0)
- {
- // correct
- this->Larger();
- this->bitarray[innIndex] = this->bitarray[innIndex] | (mask >> bitPos);
- }
- else
- {
- // error
- }
- }
- else
- {
- // there may be something error, or some code missing
- }
- }
- int BITVector::Get(int index)
- {
- if(index < size*bits)
- {
- int position = index & (bits-1); // % bits
- int innIndex = index/bits;
- __int64 i = this->bitarray[innIndex] & (mask >> position);
- if(i == 0)
- {
- return 0;
- }
- else
- {
- return 1;
- }
- }
- throw "access out of the array";
- }
- int BITVector::Size()
- {
- return size*bits;
- }
- // int integer is 0x01010111
- // start is the start position of bitvector, and start starts zero
- // len is length of the number of bits you want set into bit array
- void BITVector::SetInt(unsigned int integer,int start, int len)
- {
- int finalPos = start + len;
- int i=start;
- int j = 0;
- int temp = 0;
- for(;i < finalPos; i++,j++)
- {
- temp = integer & (0x80000000 >> j);
- this->Set(i,temp);
- }
- }
- void BITVector::PrintfZeroOne(int start,int len)
- {
- int finalPos = start+len;
- int temp = 0;
- for(int i = start; i < finalPos; i++)
- {
- printf("%d",this->Get(i));
- }
- }
- // start is where to insert bit vector c
- // len is the length of bits inserted
- // "start" is of this, and "len" is of c;
- void BITVector::SetBitVector(BITVector & c, int start, int len)
- {
- for(int i = 0; i < len; i++)
- {
- this->Set(start+i,c.Get(i));
- }
- }
- // copy construct
- BITVector::BITVector(const BITVector & bitVector):mask(0x8000000000000000),bits(sizeof(__int64)*8)
- {
- this->size = bitVector.size;
- this->bitarray = new __int64[this->size];
- memcpy(this->bitarray,bitVector.bitarray,sizeof(__int64)*bitVector.size);
- }
- const BITVector& BITVector::operator=(const BITVector& bitVector)
- {
- if(this != &bitVector)
- {
- this->size = bitVector.size;
- delete [] this->bitarray;
- this->bitarray = new __int64[this->size];
- memcpy(this->bitarray,bitVector.bitarray,sizeof(__int64)*this->size);
- }
- return * this;
- }