编程练习——可变长bit数组(bitArray)
其实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
- 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 )size2);
- 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 ;
- }