3

我想创建一个数组,它的每个单元格在 C++ 中只有 2 位。有什么办法吗?

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

4

3 回答 3

3

如果你想从头开始写这个:

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

我相信您可以在网上找到大量的开源实现,其中一个例子是 Java 的BitSet(可在此处获得)。您可能也可以在bitset某个地方找到 C++。

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

如果您可以使用标准库类:

这是我快速整理的内容。

我写了一个twoBitSet扩展类std::bitset,它本质上是一个位数组;然后它将一些提供的索引映射到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对象。

现场演示

于 2013-10-21T12:25:35.100 回答
1

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

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

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

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

于 2013-10-21T11:03:44.817 回答
0

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

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

于 2013-10-21T11:10:41.603 回答