繁体   English   中英

C ++中的位数组

[英]Bit Array in C++

在使用Project Euler问题时,我经常需要大型(> 10 ** 7)位数组。

我的正常方法是:

bool* sieve = new bool[N];

bool sieve[N];

当N = 1,000,000时,我的程序使用1兆字节(8 * 1,000,000位)。

在c ++中使用存储位数组是否比bool更有效?

使用std::bitset (如果N是常量),否则使用std::vector<bool>就像其他人提到的那样(但不要忘记阅读Herb Sutter的这篇优秀文章

bitset是一个特殊的容器类,用于存储位(只有两个可能值的元素:0或1,true或false,......)。

该类与常规数组非常相似, 但优化空间分配 :每个元素只占一位(比C ++中最小的元素类型小八倍:char)。

编辑

Herb Sutter(在那篇文章中)提到了这一点

std :: vector <bool>不合格的原因是它为了优化空间而在底层提取技巧:而不是为每个bool [1]存储一个完整的char或int(占用至少8倍的空间) ,在具有8位字符的平台上), 它打包bool并将它们作为单独的位 (内部,比如,字符)存储在其内部表示中。

std :: vector <bool>通过将其包含在标准中来强制对所有用户进行特定优化。 这不是一个好主意; 不同的用户有不同的要求,现在所有向量用户都必须支付性能损失,即使他们不想要或不需要节省空间。

编辑2

如果你使用过Boost,你可以使用boost::dynamic_bitset (如果N在运行时已知)

无论好坏, std::vector<bool>将使用位而不是bool,以节省空间。 所以只需使用std::vector就像你应该在第一时间一样。

如果N是常量 ,则可以使用std::bitset

你可以查找std::bitsetstd::vector<bool> 后者通常被推荐反对,因为尽管名称中的vector ,它实际上并不像任何其他类型的对象的矢量,并且实际上不满足一般容器的要求。 尽管如此,它可能非常有用。

OTOH,没有任何东西(至少可靠地)以不到100万比特存储100万个bool值。 它根本无法确定。 如果你的位集包含一定程度的冗余,那么有各种压缩方案可能是有效的(例如,LZ *,霍夫曼,算术),但是如果不了解内容,就不可能说它们是肯定的。 但是,这些中的任何一个通常都会将每个bool / bit存储在一个存储位中(加上一点点用于簿记的开销 - 但这通常是一个常量,并且最多为字节到几十个字节)。

仅使用1位不存储'bool'类型。 根据你对大小的评论,似乎每个bool使用1个整个字节。

AC喜欢这样做的方式是:

uint8_t sieve[N/8]; //array of N/8 bytes

然后逻辑OR字节一起得到你所有的位:

sieve[0] = 0x01 | 0x02; //this would turn on the first two bits

在该示例中,0x01和0x02是表示字节的十六进制数字。

是的,你可以使用bitset

您可能有兴趣尝试BITSCAN库作为替代方案。 最近有一个扩展已被提议用于稀疏性,我不确定是你的情况,但可能是。

您可以使用字节数组和索引。 索引n将在字节索引n/8 ,位# n%8 (如果由于某种原因std :: bitset不可用)。

如果在编译时已知N,则使用std :: bitset ,否则使用boost :: dynamic_bitset

仅使用1位不存储'bool'类型。 根据你对大小的评论,似乎每个bool使用1个整个字节。

AC喜欢这样做的方式是:

uint8_t sieve[N/8]; //array of N/8 bytes

数组的元素是:

result = sieve[index / 8] || (1 << (index % 8)); 

要么

result = sieve[index >> 3] || (1 << (index & 7));

在数组中设置1:

sieve[index >> 3] |= 1 << (index & 7);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM