C++中的位数组

Set*_*eth 20 c++ arrays bit

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

我的正常方法是:

bool* sieve = new bool[N];

bool sieve[N];
Run Code Online (Sandbox Code Playgroud)

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

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

Pra*_*rav 24

使用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在运行时已知)


GMa*_*ckG 13

无论好坏,std::vector<bool>都会使用比特代替bool,以节省空间.所以std::vector就像你本来应该使用的那样.

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


Jer*_*fin 5

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

OTOH,没有什么可以(至少可靠地)在不到 100 万位中存储 100 万个布尔值。它根本无法确定。如果您的位集包含一定程度的冗余,则有多种可能有效的压缩方案(例如 LZ*、Huffman、算术),但如果不了解内容,就无法确定它们会是有效的。然而,这些中的任何一个通常只会将每个 bool/bit 存储在一个存储位中(加上少量的簿记开销 - 但这通常是一个常量,并且最多字节到几十个字节)。