编程练习——可变长bit数组(bitArray)

其实c++里有bitset这个类,但是bitset使用时必须给定大小。例如

bitset<8> c;//这里必须在编码里写死,不能使用变量替代

c = 234;

我主要是用这个东西来存储可变长的huffman编码。所以这个类对我根本不能用。除非开始就给一个足够大的bitset。

所以我创建里一个可变长的bit vector用于存放Huffman编码。

在这里内部使用的是__int64,64位。当然根据实际需要可以将这个做为模板传入,不过现在还没有这样编码。

  1. /* created by chico chen
  2. *  date 2008/10/25
  3. */
  4. #ifndef BIT_VECTOR
  5. #define BIT_VECTOR
  6. #include 
  7. using namespace std;
      1. class BITVector
  8. {
  9. private :
  10. __int64 * bitarray;
  11. const int bits;
  12. const unsigned __int64 mask ;
  13. int size;
  14. void SetOne( int index); // x is 0
  15. void SetZero( int index); // x is 1
  16. void Larger();
    1. public :
  17. BITVector( void );
  18. void Set( int index, int x); // x is 0 or 1
  19. int Get( int index);
  20. int Size();
  21. void SetInt(unsigned int integer, int start, int len);
  22. void PrintfZeroOne( int start , int len); // print the unsigned it as 0 or 1
  23. void SetBitVector(BITVector & c, int start, int len);
  24. const BITVector& operator=( const BITVector& bitVector);
  25. explicit BITVector( const BITVector & bitVector);
    1. public :
  26. ~BITVector( void );
  27. };
  28. #endif

然后是bitVector.cpp文件

  1. /* created by chico chen
  2. *  date 2008/10/25
  3. */
  4. #include “StdAfx.h”
  5. #include “BITVector.h”
    1. BITVector::BITVector( void ):mask(0x8000000000000000),bits( sizeof ( __int64 )*8)
  6. {
  7. bitarray = new __int64 [1];
  8. memset(bitarray,0, sizeof ( __int64 ));
  9. size = 1;
  10. }
    1. BITVector::~BITVector( void )
  11. {
  12. size = 0;
  13. delete [] bitarray;
  14. }
    1. void BITVector::Set( int index, int x)
  15. {
  16. if (x == 0)
  17. {
  18. return SetZero(index);
  19. }
  20. else
  21. {
  22. return SetOne(index);
  23. }
  24. }
    1. void BITVector::SetZero( int index)
  25. {
  26. int innIndex = index/bits;
  27. int bitPos = index & (bits-1); // innIndex % 8
  28. if ( innIndex < size)
  29. {
  30. // vector maybe has enough space to store this .
  31. this ->bitarray[innIndex] = this ->bitarray[innIndex] & ~(mask >> bitPos);
  32. }
  33. else if (innIndex == size)
  34. {
  35. // should larger the size of bitarray
  36. // and innIndex must be the first bit of last char
    1. if (bitPos == 0)
  37. {
  38. // correct
  39. this ->Larger();
  40. this ->bitarray[innIndex] = this ->bitarray[innIndex] & ~(mask >> bitPos);
    1. }
  41. else
  42. {
  43. // error
    1. }
  44. }
  45. else
  46. {
  47. // there may be something error, or some code missing
    1. }
  48. }
      1. void BITVector::Larger()
  49. {
  50. __int64 * tempArray = new __int64 [size];
  51. memcpy(tempArray, this ->bitarray, sizeof ( __int64 )*size);
  52. delete [] this ->bitarray;
    1. this ->bitarray = new __int64 [size*2]; // may be error
  53. memset(bitarray,0, sizeof ( __int64 )size2);
  54. memcpy( this ->bitarray,tempArray, sizeof ( __int64 )*size);
  55. size = size*2;
  56. delete [] tempArray;
      1. }
    1. void BITVector::SetOne( int index)
  57. {
  58. int innIndex = index/bits; // you can use >>(bits-1)
  59. int bitPos = index % bits; // innIndex & (bits-1)
  60. if ( innIndex < size)
  61. {
  62. // vector maybe has enough space to store this .
  63. this ->bitarray[innIndex] = this ->bitarray[innIndex] | (mask >> bitPos);
  64. }
  65. else if (innIndex == size)
  66. {
  67. // should larger the size of bitarray
  68. // and innIndex must be the first bit of last char
    1. if (bitPos == 0)
  69. {
  70. // correct
  71. this ->Larger();
  72. this ->bitarray[innIndex] = this ->bitarray[innIndex] | (mask >> bitPos);
    1. }
  73. else
  74. {
  75. // error
    1. }
  76. }
  77. else
  78. {
  79. // there may be something error, or some code missing
    1. }
    1. }
    1. int BITVector::Get( int index)
  80. {
  81. if (index < size*bits)
  82. {
  83. int position = index & (bits-1); // % bits
  84. int innIndex = index/bits;
  85. __int64 i = this ->bitarray[innIndex] & (mask >> position);
  86. if (i == 0)
  87. {
  88. return 0;
  89. }
  90. else
  91. {
  92. return 1;
  93. }
  94. }
  95. throw “access out of the array” ;
  96. }
    1. int BITVector::Size()
  97. {
  98. return size*bits;
  99. }
    1. // int integer is 0x01010111
  100. // start is the start position of bitvector, and start starts zero
  101. // len is length of the number of bits you want set into bit array
  102. void BITVector::SetInt(unsigned int integer, int start, int len)
  103. {
  104. int finalPos = start + len;
  105. int i=start;
  106. int j = 0;
  107. int temp = 0;
  108. for (;i < finalPos; i++,j++)
  109. {
  110. temp = integer & (0x80000000 >> j);
  111. this ->Set(i,temp);
  112. }
  113. }
      1. void BITVector::PrintfZeroOne( int start, int len)
  114. {
  115. int finalPos = start+len;
  116. int temp = 0;
  117. for ( int i = start; i < finalPos; i++)
  118. {
  119. printf( “%d” , this ->Get(i));
  120. }
  121. }
    1. // start is where to insert bit vector c
  122. // len is the length of bits inserted
  123. // “start” is of this, and “len” is of c;
  124. void BITVector::SetBitVector(BITVector & c, int start, int len)
  125. {
    1. for ( int i = 0; i < len; i++)
  126. {
  127. this ->Set(start+i,c.Get(i));
  128. }
    1. }
    1. // copy construct
  129. BITVector::BITVector( const BITVector & bitVector):mask(0x8000000000000000),bits( sizeof ( __int64 )*8)
  130. {
  131. this ->size = bitVector.size;
  132. this ->bitarray = new __int64 [ this ->size];
  133. memcpy( this ->bitarray,bitVector.bitarray, sizeof ( __int64 )*bitVector.size);
  134. }
    1. const BITVector& BITVector::operator=( const BITVector& bitVector)
  135. {
  136. if ( this != &bitVector)
  137. {
  138. this ->size = bitVector.size;
  139. delete [] this ->bitarray;
  140. this ->bitarray = new __int64 [ this ->size];
  141. memcpy( this ->bitarray,bitVector.bitarray, sizeof ( __int64 )* this ->size);
  142. }
  143. return * this ;
  144. }