我需要存储大约 10000 个变量的布尔信息。首先我想使用一个布尔数组 arr[10000] 但它需要 40000 个字节。但我需要以一种内存有效的方式存储这些信息。也许使用位操作?还有一件事我需要全局存储它并动态分配它。你能帮我解决这个问题吗?
6 回答
你可以这样做:
vals = new char[(len+7)/8];
// To access
vals[i/8] & 1 << (i % 8)
// To set
vals[i/8] |= 1 << (i % 8);
// To clear
vals[i/8] &= ~(char)(1 << (i % 8));
虽然要最快,但您应该使用任何字长大小的块。所以在 32 位计算机上:
vals = new uint32_t[(len+31)/32];
// To access
vals[i/32] & 1 << (i % 32)
// To set
vals[i/32] |= 1 << (i % 32);
// To clear
vals[i/32] &= ~(uint32_t)(1 << (i % 32));
在 C++ 中,您可以选择std::bitset<10000>
以固定大小存储单个位,或者std::vector<bool>
如果您需要动态更改大小。这两个都将使用每个值一个位。
没有太多需要手动进行位摆弄。
显然,最有效的方法是稍微存储一个值。Wich 将减少 8 倍的内存。
我会制作一个位字段数组,如下所示。正好是 10000... 对于动态分配,只需将 BoolBytes 设为指针,使用 malloc 和 bob 即可。
typedef struct
{
unsigned b0 :1;
unsigned b1 :1;
unsigned b2 :1;
unsigned b3 :1;
unsigned b4 :1;
unsigned b5 :1;
unsigned b6 :1;
unsigned b7 :1;
}BitField;
BitField BoolBytes[1250]; // The number of bools is OVER NINE-THOUSAAAAAAAND!
另一个“效率”问题是询问 8 倍的内存是否比在内存中执行 10000 个布尔的地址计算所增加的时间更好。开销不大,但这会比布尔数组稍慢。
使用std::vector<bool>
应该是最简单的方法。您可以只使用众所周知的矢量接口(它带有动态分配,例如,通过使用push_back
向其中添加项目),而我知道的所有 stl 实现(我不确定它是否也是定义所必需的)使用模板布尔向量的专门化并将其实现为每个值 1 位。
请注意,动态重新分配(您不必关心它,这一切都由向量类完成)将允许插入的恒定摊销时间,但可能会有内存开销(实际位数的一小部分)到允许这个。特别是,在需要时,调整大小会将分配的内存扩展/缩小当前长度的一小部分。
虽然这不是每次存储信息所需的最小内存,但我仍然认为它是一种内存有效的方式。