битовые векторы в c++ [закрыто]

недавно я слышал о битовых векторах, но я не могу найти полезную информацию или учебники по этой теме. Можете ли вы предложить книгу или краткий учебник о том, как реализовать свои собственные классы битовых векторов? Спасибо.

- - - // / / Я не могу опубликовать ответы на свои вопросы, поэтому я решил отредактировать этот пост. вот что я только что нашел:"структура данных для игровых программистов - Рона Пентона и Андре Ламота". Глава 4, Bitvectors. Эта книга имеет подробное объяснение битовых векторов, и как сделать класс bit vector самостоятельно. повеселись.

2 ответов


вот очень простая реализация битового вектора статического размера. Это требует C++11 функции, поскольку он полагается на <cstdint> заголовок, но этот заголовок довольно часто встречается поскольку он основан на стандарте C99 функции. В крайнем случае вы можете использовать C <stdint.h> заголовок и просто использовать типы в глобальном пространстве имен.

Примечание: это было набрано на лету и не тестируется вообще. Я даже не проверил, что он будет компилироваться. Так, может быть ошибки.

#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.
}

весь my_bitvector_base всего создать некий отдельный тип. Вы можете упомянуть об этом в интерфейсе или реализации для производных классов, потому что это protected, но вы не можете упомянуть об этом в других контекстах. Это не позволяет людям хранить копию bitref. Это важно, потому что bitref существует только для того, чтобы разрешить присвоение результата operator [] потому что комитет по стандартам C++, во всей своей мудрости, не реализовал operator []= или что-то аналогично для назначения элементу array.

как вы можете видеть, битовый вектор в основном представляет собой массив битов. Более модные битовые векторы будут имитировать "бесконечный" массив битов, инициализированных true или false. Они делают это, отслеживая самый последний бит, который был установлен, и все биты перед ним. И если вы попросите немного после этого, они просто вернут инициализированное значение.

хороший бит-вектор также будет реализован operator & и другие такие тонкости, поэтому они ведут себя как очень большое целое число без знака со ссылкой на операции битовой манипуляции.


vector - это специализация векторного шаблона. Для нормальной переменной bool требуется хотя бы один байт, но так как только bool имеет два состояния идеальная реализация вектора такова, что для каждого значения bool требуется только один бит. Это означает, что итератор должен быть специально определенный, и не может быть bool*.

от мышления CPP Vol-2 от Брюса Экеля Глава 4: контейнеры и итераторы STL

книгу можно скачать бесплатно на http://www.mindviewinc.com/Books/downloads.html и он содержит больше информации о битах и C++