我有一个由随机数生成器生成的字节数组。我想把它放到STL位集中。
不幸的是,看起来Bitset只支持以下构造函数:
我现在能想到的唯一解决方案是逐位读取字节数组并创建一个1和0的字符串。有没有人有更有效的解决方案?
答案 0 :(得分:7)
这样的东西? (不确定模板魔法是否像我期望的那样在这里工作。我在C ++中生锈了。)
std::bitset bytesToBitset<int numBytes>(byte *data)
{
std::bitset<numBytes * CHAR_BIT> b;
for(int i = 0; i < numBytes; ++i)
{
byte cur = data[i];
int offset = i * CHAR_BIT;
for(int bit = 0; bit < CHAR_BIT; ++bit)
{
b[offset] = cur & 1;
++offset; // Move to next bit in b
cur >>= 1; // Move to next bit in array
}
}
return b;
}
答案 1 :(得分:3)
bitset<>
有一个第3个构造函数 - 它不带任何参数并将所有位设置为0.我认为你需要使用它然后遍历调用set()
的数组中的每一位字节数组是1。
有点蛮力,但它会起作用。将每个字节中的字节索引和位偏移转换为位集索引会有一些复杂性,但它没有任何想法(可能在调试器下运行)无法解决。我认为它比通过字符串转换或流来运行数组更可能更简单,更有效。
答案 2 :(得分:2)
伙计们,我花了很多时间写一个反向函数(bitset - &gt; byte / char数组)。那是:
bitset<SIZE> data = ...
// bitset to char array
char current = 0;
int offset = 0;
for (int i = 0; i < SIZE; ++i) {
if (data[i]) { // if bit is true
current |= (char)(int)pow(2, i - offset * CHAR_BIT); // set that bit to true in current masked value
} // otherwise let it to be false
if ((i + 1) % CHAR_BIT == 0) { // every 8 bits
buf[offset++] = current; // save masked value to buffer & raise offset of buffer
current = 0; // clear masked value
}
}
// now we have the result in "buf" (final size of contents in buffer is "offset")
答案 3 :(得分:2)
嗯,说实话,我很无聊,并开始认为必须比设置每一位稍快一点。
template<int numBytes>
std::bitset<numBytes * CHARBIT bytesToBitset(byte *data)
{
std::bitset<numBytes * CHAR_BIT> b = *data;
for(int i = 1; i < numBytes; ++i)
{
b <<= CHAR_BIT; // Move to next bit in array
b |= data[i]; // Set the lowest CHAR_BIT bits
}
return b;
}
这确实稍微快一些,至少只要字节数组小于30个元素(取决于传递给编译器的优化标志)。比这更大的数组和移位位集所用的时间使得每个位的设置更快。
答案 4 :(得分:0)
您可以从流初始化bitset。我不记得如何将一个byte []压入流中,但是......
来自http://www.sgi.com/tech/stl/bitset.html
bitset<12> x;
cout << "Enter a 12-bit bitset in binary: " << flush;
if (cin >> x) {
cout << "x = " << x << endl;
cout << "As ulong: " << x.to_ulong() << endl;
cout << "And with mask: " << (x & mask) << endl;
cout << "Or with mask: " << (x | mask) << endl;
}
答案 5 :(得分:0)
这是我使用模板元编程的实现 循环在编译时完成 我拿了@strager版本,修改它以准备TMP:
运行时带循环的修改版本:
StyledEditorKit.AlignmentAction
基于它的TMP版本:
template <size_t nOfBytes>
void bytesToBitsetRunTimeOptimized(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) {
for(int i = nOfBytes - 1; i >= 0; --i) {
for(int bit = 0; bit < CHAR_BIT; ++bit) {
result[i * CHAR_BIT + bit] = ((arr[i] >> bit) & 1);
}
}
}
客户代码:
template<size_t nOfBytes, int I, int BIT> struct LoopOnBIT {
static inline void bytesToBitset(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) {
result[I * CHAR_BIT + BIT] = ((arr[I] >> BIT) & 1);
LoopOnBIT<nOfBytes, I, BIT+1>::bytesToBitset(arr, result);
}
};
// stop case for LoopOnBIT
template<size_t nOfBytes, int I> struct LoopOnBIT<nOfBytes, I, CHAR_BIT> {
static inline void bytesToBitset(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) { }
};
template<size_t nOfBytes, int I> struct LoopOnI {
static inline void bytesToBitset(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) {
LoopOnBIT<nOfBytes, I, 0>::bytesToBitset(arr, result);
LoopOnI<nOfBytes, I-1>::bytesToBitset(arr, result);
}
};
// stop case for LoopOnI
template<size_t nOfBytes> struct LoopOnI<nOfBytes, -1> {
static inline void bytesToBitset(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) { }
};
template <size_t nOfBytes>
void bytesToBitset(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) {
LoopOnI<nOfBytes, nOfBytes - 1>::bytesToBitset(arr, result);
}