Commit 91e3afc2 authored by xep's avatar xep
Browse files

2021.6.8 bitmatrix

parent 038403d0
#include <iostream>
#include <utility>
#include <stdint.h>
#include <limits>
/// <summary>
/// 具有运行时常量大小的位向量。
/// </summary>
class BitSet {
public:
using buffer_type = uint8_t;
BitSet(int size_);
BitSet(const BitSet& bs);
BitSet(BitSet&& bs)noexcept;
~BitSet();
BitSet& operator=(const BitSet& bs) = delete;
BitSet& operator=(BitSet&& bs)noexcept = delete;
bool test(int i)const;
inline bool operator[](int i)const {
//note: not assignmentable
return test(i);
}
BitSet& set(int i);
BitSet& reset(int i);
BitSet& flip(int i);
BitSet& set();
BitSet& reset();
BitSet& flip();
inline int get_size()const {
return size;
}
void show()const;
private:
const int size, bufsize;
buffer_type* buffer;
static constexpr int buf_bits = 8 * static_cast<int>(sizeof(buffer_type));
static constexpr buffer_type
BUF_ONE = std::numeric_limits<buffer_type>::max(),
BUF_ZERO = std::numeric_limits<buffer_type>::min();
static constexpr int get_buffer_pos(int i);
static constexpr buffer_type get_bit_one_buffer(int i);
static constexpr buffer_type get_bit_zero_buffer(int i);
};
BitSet::BitSet(int size_) :size(size_), bufsize((size_ - 1) / buf_bits + 1)
{
buffer = new buffer_type[bufsize];
}
BitSet::BitSet(const BitSet& bs) : size(bs.size), bufsize(bs.bufsize)
{
buffer = new buffer_type[bufsize];
std::copy(bs.buffer, bs.buffer + bufsize, buffer);
}
BitSet::BitSet(BitSet&& bs) noexcept :
size(bs.size), bufsize(bs.bufsize), buffer(bs.buffer)
{
bs.buffer = nullptr;
}
BitSet::~BitSet()
{
if (buffer) {
delete[] buffer;
buffer = nullptr;
}
}
bool BitSet::test(int i) const
{
return buffer[get_buffer_pos(i)] & get_bit_one_buffer(i);
}
BitSet& BitSet::set(int i)
{
buffer[get_buffer_pos(i)] |= get_bit_one_buffer(i);
return *this;
}
BitSet& BitSet::reset(int i)
{
buffer[get_buffer_pos(i)] &= get_bit_zero_buffer(i);
return *this;
}
BitSet& BitSet::flip(int i)
{
buffer[get_buffer_pos(i)] ^= get_bit_one_buffer(i);
return *this;
}
BitSet& BitSet::set()
{
for (int i = 0; i < bufsize - 1; i++) {
buffer[i] = BUF_ONE;
}
for (int i = (bufsize - 1) * buf_bits; i < size; i++) {
set(i);
}
return *this;
}
BitSet& BitSet::reset()
{
for (int i = 0; i < bufsize - 1; i++) {
buffer[i] = BUF_ZERO;
}
for (int i = (bufsize - 1) * buf_bits; i < size; i++) {
reset(i);
}
return *this;
}
BitSet& BitSet::flip()
{
for (int i = 0; i < bufsize; i++) {
buffer[i] = ~buffer[i];
}
return *this;
}
void BitSet::show() const
{
for (int i = 0; i < size; i++) {
std::cout << (int)test(i);
}
std::cout << std::endl;
}
constexpr int BitSet::get_buffer_pos(int i)
{
return i / buf_bits; //int div
}
constexpr typename BitSet::buffer_type BitSet::get_bit_one_buffer(int i)
{
return static_cast<buffer_type>(1) << (buf_bits - 1 - (i % buf_bits));
}
constexpr typename BitSet::buffer_type BitSet::get_bit_zero_buffer(int i)
{
return ~get_bit_one_buffer(i);
}
class BitMatrix :private BitSet {
const int row, col;
public:
BitMatrix(int row_, int col_):row(row_),col(col_),BitSet(row_*col_){}
BitMatrix(const BitMatrix& bm):row(bm.row),col(bm.col),BitSet(bm){}
BitMatrix(BitMatrix&& bm)noexcept:row(bm.row),col(bm.col),BitSet(bm){}
inline bool test(int i,int j)const {
return BitSet::test(get_index(i, j));
}
inline void set(int i, int j) {
BitSet::set(get_index(i, j));
}
inline void reset(int i, int j) {
BitSet::reset(get_index(i, j));
}
inline void flip(int i, int j) {
BitSet::flip(get_index(i, j));
}
inline void set() { BitSet::set(); }
inline void reset() { BitSet::reset(); }
inline void flip() { BitSet::flip(); }
inline int get_index(int i, int j)const {
return i * col + j;
}
};
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment