我想在数组中存储位(如结构).所以我可以遵循以下两种方法之一
方法1(AN 1)
struct BIT
{
int data : 1
};
int main()
{
BIT a[100];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
方法2(AN 2)
int main()
{
std::bitset<100> BITS;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么有人比AN 1更喜欢AN 2?
我正在研究C++中的一些简单的位操作问题,并在尝试可视化我的步骤时遇到了这个问题.我知道分配给不同基元类型的位数可能因系统而异.对于我的机器,sizeof(int)输出4,所以我的char价值有4 位.我现在也知道一个字节的定义通常是8位,但不一定是这种情况.当我输出CHAR_BIT我得到8.因此,我希望我的int值总共有32位.
然后我可以继续将我的二进制值打印int到屏幕上:
int max=~0; //All my bits are turned on now
std::cout<<std::bitset<sizeof(int)*CHAR_BIT>(max)<<std::endl;
$:11111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)
如果我想要,我可以增加bitset大小:
int max=~0;
std::cout<<std::bitset<sizeof(int)*CHAR_BIT*3>(max)<<std::endl;
$:000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)
为什么有这么多?我本来期望只有32个,用零填充.相反,有两倍,发生了什么?
当我重复实验unsigned int,其大小相同时int,额外的实验不会出现:
unsigned int unmax=~0;
std::cout<<std::bitset<sizeof(unsigned int)*CHAR_BIT*3>(unmax)<<std::endl;
$:000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud) 这主要是语言律师的问题,我怀疑大多数实现都会麻烦,特别是因为这可能会增加每个用户的编译时间。
话虽如此:如果对std :: set的某些实现是针对每个实例和共享的256个值的静态数组使用位集实现的(由于键为const,这是安全的),根据该标准,这是否合法?
枚举标志的使用位集的优缺点是什么?
namespace Flag {
enum State {
Read = 1 << 0,
Write = 1 << 1,
Binary = 1 << 2,
};
}
namespace Plain {
enum State {
Read,
Write,
Binary,
Count
};
}
int main()
{
{
unsigned int state = Flag::Read | Flag::Binary;
std::cout << state << std::endl;
state |= Flag::Write;
state &= ~(Flag::Read | Flag::Binary);
std::cout << state << std::endl;
} {
std::bitset<Plain::Count> state;
state.set(Plain::Read);
state.set(Plain::Binary);
std::cout << state.to_ulong() << std::endl;
state.flip();
std::cout << state.to_ulong() …Run Code Online (Sandbox Code Playgroud) 我正在寻找一种在Java中存储密集可变长度比特阵的非常紧凑的方法.现在,我正在使用BitSet,但它似乎平均使用1.5*n位存储空间用于大小为n的位向量.通常,这不是问题,但在这种情况下,存储的比特阵列是应用程序的内存占用量非常重要的部分.因此,让它们变得更小一点真的很有帮助.
BitSet所需的空间似乎是由于用于支持数据结构的long数组在每次扩展以容纳更多位时往往会加倍:
// BitSet's resizing code
private void ensureCapacity(int wordsRequired) {
if (words.length < wordsRequired) {
// Allocate larger of doubled size or required size
int request = Math.max(2 * words.length, wordsRequired);
words = Arrays.copyOf(words, request);
sizeIsSticky = false;
}
}
Run Code Online (Sandbox Code Playgroud)
我可以编写自己的BitSet替代实现,更加保守地扩展后端数据结构.但是,如果我不需要,我真的很讨厌复制标准类库中已有的功能.
我已经拿起了这个将BitSet转换为Byte数组的例子.
public static byte[] toByteArray(BitSet bits) {
byte[] bytes = new byte[bits.length()/8+1];
for (int i=0; i<bits.length(); i++) {
if (bits.get(i)) {
bytes[bytes.length-i/8-1] |= 1<<(i%8);
}
}
return bytes;
}
Run Code Online (Sandbox Code Playgroud)
但在讨论论坛中,我已经看到,通过这种方法,我们不会得到所有的位,因为我们将在每次计算时丢失一位.这是真的?我们需要修改上面的方法吗?
为什么这个程序显示以下输出?
#include <bitset>
...
{
std::bitset<8> b1(01100100); std::cout<<b1<<std::endl;
std::bitset<8> b2(11111111); std::cout<<b2<<std::endl; //see, this variable
//has been assigned
//the value 11111111
//whereas, during
//execution, it takes
//the value 11000111
std::cout << "b1 & b2: " << (b1 & b2) << '\n';
std::cout << "b1 | b2: " << (b1 | b2) << '\n';
std::cout << "b1 ^ b2: " << (b1 ^ b2) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
01000000
11000111
b1 & b2: 01000000
b1 | b2: 11000111
b1 ^ b2: 10000111 …Run Code Online (Sandbox Code Playgroud) 这个size()方法有没有用例java.util.BitSet?
我的意思是 - JavaDoc明确表示它依赖于实现,它long[]以位为单位返回内部存储的大小.从它所说的,可以得出结论,你将无法设置一个索引高于size(),但不是这样,BitSet可以自动增长:
BitSet myBitSet = new BitSet();
System.out.println(myBitSet.size()); // prints "64"
myBitSet.set(768);
System.out.println(myBitSet.size()); // prints "832"
Run Code Online (Sandbox Code Playgroud)
在BitSet我生命中遇到的每一次遭遇中,我一直想使用,length()因为那个回归的逻辑大小BitSet:
BitSet myBitSet = new BitSet();
System.out.println(myBitSet.length()); // prints "0"
myBitSet.set(768);
System.out.println(myBitSet.length()); // prints "769"
Run Code Online (Sandbox Code Playgroud)
即使我在过去的6年里一直在编写Java,但这两种方法对我来说总是很困惑.我经常混合起来,并顺便用错了,因为在我的头上,我觉得BitSet作为一个聪明的Set<boolean>,我会用size().
这就像如果ArrayList已经length()返回元件的数量和size()返回底层数组的大小.
现在,size()我缺少哪种方法的用例?它有用吗?有没有人用它做任何事情?对于某些手动钻头或类似的东西来说,这可能很重要吗?
编辑(经过一些更多的研究)
我意识到BitSet是在Java 1.0中引入的,而我们使用的大多数类的Collections框架都是在Java 1.2中引入的.所以基本上在我看来,size()由于遗留原因而保留,并且没有真正的用途.新的Collection类没有这样的方法,而一些旧的(Vector例如).
我试图实现一个BloomFilter,并遇到了一些关于BitSets的讨论.Lucene OpenBitSet声称它几乎在所有操作中都比Java BitSet实现更快.
我试着查看两个实现的代码.
Java BitSet代码
在我看来,这两个类都使用'long'数组来存储这些位.各个位映射到特定的数组索引和存储在索引处的"long"值中的位位置.
是什么原因,那么OpenBitSet实现在性能方面要好得多?导致速度提高的代码差异在哪里?
为什么bitset以相反的顺序存储这些位?经过多次打击后,我终于写了这个binary_to_dec.可以简化吗?
int binary_to_dec(std::string bin)
{
std::bitset<8> bit;
int c = bin.size();
for (size_t i = 0; i < bin.size(); i++,c--)
{
bit.set(c-1, (bin[i]-'0' ? true : false));
}
return bit.to_ulong();
}
Run Code Online (Sandbox Code Playgroud)