Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;_C++_Arrays_Bit - Fatal编程技术网

C++ C++;

C++ C++;,c++,arrays,bit,C++,Arrays,Bit,在处理项目Euler问题时,我通常需要大(>10**7)位数组 我通常的做法是: bool* sieve = new bool[N]; bool sieve[N]; 当N=1000000时,我的程序使用1兆字节(8*1000000位) 在C++中,是否有一种比BoL更有效的存储位数组的使用方法?< /P> < P>使用(如果 N< /代码>是常数),否则使用 STD::向量< /代码>(如其他人所提到的)(但不要忘记由Habor萨特阅读) 位集是一种特殊的容器类,用于存储位(只有两个可能值的

在处理项目Euler问题时,我通常需要大(>10**7)位数组

我通常的做法是:

bool* sieve = new bool[N];

bool sieve[N];
当N=1000000时,我的程序使用1兆字节(8*1000000位)

在C++中,是否有一种比BoL更有效的存储位数组的使用方法?< /P> < P>使用(如果<代码> N< /代码>是常数),否则使用<代码> STD::向量< /代码>(如其他人所提到的)(但不要忘记由Habor萨特阅读)

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

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

编辑

Herb Sutter(在那篇文章中)提到

std::vector不符合要求的原因是,为了优化空间,它隐藏了一些技巧:它不是为每个bool[1]存储一个完整的字符或int(在具有8位字符的平台上,它至少占用8倍的空间),而是将bool打包并作为单个位存储(比如,在字符内部)在其内部代表中

std::vector通过将其纳入标准,强制所有用户进行特定优化。这不是一个好主意;不同的用户有不同的需求,现在vector的所有用户都必须支付性能罚款,即使他们不想或不需要节省空间

编辑2


如果您使用过Boost,您可以使用(如果运行时知道
N

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

无论好坏,
std::vector
将使用位而不是布尔位,以节省空间。所以只要使用std::vector,就像你应该首先使用的那样


如果
N
是一个常数,您可以使用
std::bitset

您可以查找
std::bitset
std::vector
。后者通常被建议反对,因为尽管名称中有
向量
,但它实际上并不象任何其他类型对象的向量,事实上也不符合容器的一般要求。尽管如此,它还是非常有用的


OTOH,没有任何东西能够(至少可靠地)在不到100万位的时间内存储100万个布尔值。这根本不能肯定地做到。如果您的位集包含一定程度的冗余,则可能存在各种有效的压缩方案(例如,LZ*、哈夫曼、算术),但如果不了解内容,则无法确定它们是否有效。然而,这两种方法中的任何一种通常只将每个bool/位存储在一个存储位中(加上一点簿记开销——但这通常是一个常量,最多以字节到几十字节的顺序)。

bool类型不是仅使用1位存储的。从您对大小的评论来看,似乎每个bool使用1个完整字节

类似C的方法是:

uint8_t sieve[N/8]; //array of N/8 bytes
uint8_t sieve[N/8]; //array of N/8 bytes
然后将逻辑或字节组合在一起以获得所有位:

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

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

如果N在编译时已知,请使用,否则请使用。

您可能有兴趣尝试使用该库作为替代。最近有人提议对稀疏性进行扩展,我不确定你的情况是否如此,但可能是这样

不能仅使用1位存储“bool”类型。从您对大小的评论来看,似乎每个bool使用1个完整字节

类似C的方法是:

uint8_t sieve[N/8]; //array of N/8 bytes
uint8_t sieve[N/8]; //array of N/8 bytes
数组的元素是:

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

result=sieve[index/8]| |(1>3]| |(1>3]|=1我使用向量实现了sieve的算法。它可以容纳那么多数字。可能是上选的重复,好主意,可能是,它是N/8+1,它是位压缩数组。