2011-12-19 20 views
5

Recientemente escuché acerca de los vectores de bits, pero realmente no puedo encontrar información útil o tutoriales sobre este tema. ¿Puede sugerir un libro o un tutorial rápido sobre cómo implementar sus propias clases de vectores de bits? Gracias.vectores de bits en C++

--- /// No puedo publicar respuestas a mis propias preguntas, así que decidí editar esta publicación. esto es lo que acabo de encontrar: "Estructura de datos para programadores de juegos: Ron Penton y Andre Lamothe". Capítulo 4, Bitvectors. Este libro tiene una explicación detallada de los vectores de bits, y cómo hacer una clase de vector de bits usted mismo. que te diviertas.

+0

¿Qué desea saber * sobre * vectores de bits? En C++, normalmente usarías 'std :: bitset' o' std :: vector 'para este – jalf

+0

, ni siquiera sé para qué sirven, así que cualquier cosa servirá) –

+0

también me gustaría saber qué es la mecánica interna del bit vector. perdón por mal inglés –

Respuesta

3

Aquí hay una implementación de vector de bits de tamaño estático muy simple. Requiere C++ 11 para funcionar ya que se basa en el encabezado <cstdint>, pero este encabezado se encuentra bastante comúnmente ya que está basado en una característica C99. En una pizca, puede usar el encabezado C <stdint.h> y simplemente usar tipos en el espacio de nombres global.

Nota: Esto fue escrito sobre la marcha y no se ha probado en absoluto. Ni siquiera comprobé que compilara. Entonces, puede haber errores.

#include <cstdint> // ::std::uint64_t type 
#include <cstddef> // ::std::size_t type 
#include <algorithm> 

class my_bitvector_base { 
protected: 
    class bitref { // Prevent this class from being used anywhere else. 
    public: 
     bitref(::std::uint64_t &an_int, ::std::uint64_t mask) 
      : an_int_(an_int), mask_(mask) 
     { 
     } 

     const bitref &operator =(bool val) { 
     if (val) { 
      an_int_ |= mask_; 
     } else { 
      an_int_ &= ~mask_; 
     } 
     return *this; 
     } 
     const bitref &operator =(const bitref &br) { 
     return this->operator =(bool(br)); 
     } 
     operator bool() const { 
     return ((an_int_ & mask_) != 0) ? true : false; 
     } 

    private: 
     ::std::uint64_t &an_int_; 
     ::std::uint64_t mask_; 
    }; 
}; 

template < ::std::size_t Size > 
class my_bitvector : public my_bitvector_base { 
private: 
    static constexpr ::std::size_t numints = ((Size + 63)/64); 
public: 
    my_bitvector() { ::std::fill(array, array + numints, 0); } 

    bool operator [](::std::size_t bitnum) const { 
     const ::std::size_t bytenum = bit/64; 
     bitnum = bitnum % 64; 
     return ((ints_[bytenum] & (::std::uint64_t(1) << bitnum)) != 0) ? true : false; 
    } 
    bitref operator[](::std::size_t bitnum) { 
     const ::std::size_t bytenum = bit/64; 
     bitnum = bitnum % 64; 
     ::std::uint64_t mask = ::std::uint64_t(1) << bitnum; 
     return bitref(ints_[bytenum], mask); 
    } 

private: 
    ::std::uint64_t ints_[numints]; 
}; 

// Example uses 
void test() 
{ 
    my_bitvector<70> bits; // A 70 bit long bit vector initialized to all false 
    bits[1] = true; // Set bit 1 to true 
    bool abit = bits[1]; // abit should be true. 
    abit = bits[69]; // abit should be false. 
} 

El conjunto my_bitvector_base cosa es crear una especie de tipo privado. Puede mencionarlo en la interfaz o implementación para las clases derivadas porque es protected, pero no puede mencionarlo en otros contextos. Esto evita que las personas guarden una copia de bitref. Esto es importante porque un bitref solo existe para permitir la asignación al resultado de operator [] porque el comité de estándares de C++, en toda su sabiduría, no ha implementado operator []= o algo similar para asignar a un elemento de matriz.

Como puede ver, un vector de bits es básicamente una matriz de bits. Los vectores de bits Fancier simularán una matriz "infinita" de bits, todos inicializados en verdadero o falso. Lo hacen mediante el seguimiento del último bit que se ha establecido y todos los bits anteriores. Y si pides un poco después de eso, solo devuelven el valor inicializado.

Un vector de buen bit también implementará operator & y otras sutilezas, por lo que se comportan como un entero sin signo muy grande con referencia a las operaciones de manipulación de bits.

1

vector < ​ bool> es una especialización de la plantilla de vector. Una variable bool normal requiere al menos un byte, pero dado que un bool solo tiene dos estados, la implementación ideal del vector es tal que cada valor bool solo requiere un bit. Esto significa que el iterador debe ser especialmente definido, y no puede ser un bool *.

de pensar CPP Vol-2 de Bruce Eckel capítulo 4: contenedores STL & Iteradores

El libro se puede descargar de forma gratuita en http://www.mindviewinc.com/Books/downloads.html y contiene más información sobre los bits y C++