簡體   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