为C++中的每个单元格创建一个只有 2 位的数组

create an array with just 2 bit for each cell in C++

本文关键字:一个 数组 C++ 单元格 创建      更新时间:2023-10-16

我想创建一个数组,它的每个单元格只有 2 位C++。 有什么办法可以做到这一点吗?

有一些方法可以创建位数组,但它们只为每个单元分配一个位。

如果你想

从头开始编写这个:

可能所有位集实现使用的基本思想是具有int[](或实际上任何其他整型),并使用按位运算来获取或设置特定位。

我相信你可以在网上找到很多开源实现,一个例子是Java的BitSet(可在这里找到)。您可能也可以在某处找到C++的bitset

同样的想法也适用于这里 - 只是不是将某个索引映射到一个位,而是映射到两个位。

如果可以使用标准库类:

这是我快速整理的东西。

我写了一个扩展std::bitsettwoBitSet类,它本质上是一个位数组;然后它将一些提供的索引映射到bitset中的两个位。

还有一个twoBit帮助程序类 - 在没有 [] 运算符的情况下修改数据有些困难。

#include <iostream>
#include <bitset>
template <size_t N> 
class twoBit
{
  typedef typename std::bitset<2*N>::reference bitRef;
  bitRef a, b;
public:
  twoBit(bitRef a1, bitRef b1): a(a1), b(b1) {};
  const twoBit &operator=(int i) { a = i%2; b = i/2; return *this; };
  operator int() { return 2*b + a; };
};
template <size_t N> 
class twoBitSet : private std::bitset<2*N>
{
  typedef typename std::bitset<2*N>::reference bitRef;
public:
  twoBit<N> operator[](int index)
  {
    bitRef b1 = std::bitset<2*N>::operator[](2*index);
    bitRef b2 = std::bitset<2*N>::operator[](2*index + 1);
    return twoBit<N>(b1, b2);
  };
};
int main()
{
    twoBitSet<32> bs;
    bs[0] = 2;
    bs[1] = 3;
    bs[2] = 1;
    bs[3] = 0;
    std::cout << bs[0] << std::endl; // prints 2
    std::cout << bs[1] << std::endl; // prints 3
    std::cout << bs[2] << std::endl; // prints 1
    std::cout << bs[3] << std::endl; // prints 0
}

目前它显然是相当基本的,它只允许使用[]运算符,没有任何范围检查。

也许创建 2 个[]运算符函数(类似于 bitset )会更好 - 一个只是访问器,另一个返回twoBit对象。

现场演示。

如何创建一个包含 2 位变量和 6 位变量的结构:

struct split
{
  uint8_t sixbits : 6;
  uint8_t twobits : 2;
}

然后为此创建一个结构数组,并且只使用结构的两位部分?

注意:未测试...从这里获得信息。

std::vector<bool>有你正在寻找的专业。然后,您可以简单地将两个连续的数组元素视为一个 2 布尔值的元素,或者如果您不舒服,可以在循环中将索引增加 2 为此编写包装器类。使用 2 位变量创建类的问题在于它仍然会占用 8 位(1 字节),因为C++中最小的变量大小是 1 字节。

完全自定义的解决方案是创建字符数组(8 位),然后使用 shift 运算符使用每个字符的所有位。但是,这将非常复杂,因为每次访问值时都需要取消移动它们(...这正是std::vector<bool>专业化的工作方式)。

相关文章: