/*
* boost库中数据容器之一:dynamic_bitset
* 配置环境: win32 + codeblock + mingw32-g++ + boost.1.66
* author : Ranger_roger
* time : 2018//3/2
*
* 采用位运算往往可以取得意想不到的性能提升,位运算必然和二进制位数关联,C++为二进制位数提
* 供了两个工具std::vector<bool>和std::bitset
* 前者并不是容器,虽可动态增长,但是位运算受限;后者的bitset是标准容器,支持多样的位运算
* 但是大小固定,无法动态增长size。
* boost::dynamic_bitset则是综合两者的优点
*/
/*
template <typename Block, typename Allocator>
//Block指示以何种整数类型存储二进制位,必须是一个无符号整数,默认是unsigned long,如果二进制
//数不超过32位,为节省空间,可以采用更小的Block类型,如果unsigned char unsigned short
//Allocator是类内部使用的内存分配器,默认为std::allocator<Block>,一般这两个模板形参无需变动
class dynamic_bitset
{
// Portability note: member function templates are defined inside
// this class definition to avoid problems with VC++. Similarly,
// with the member functions of nested classes.
//
// [October 2008: the note above is mostly historical; new versions
// of VC++ are likely able to digest a more drinking form of the
// code; but changing it now is probably not worth the risks...]
BOOST_STATIC_ASSERT((bool)detail::dynamic_bitset_impl::allowed_block_type<Block>::value);
typedef std::vector<Block, Allocator> buffer_type;
public:
typedef Block block_type;
typedef Allocator allocator_type;
typedef std::size_t size_type;
typedef typename buffer_type::size_type block_width_type;
BOOST_STATIC_CONSTANT(block_width_type, bits_per_block = (std::numeric_limits<Block>::digits));
BOOST_STATIC_CONSTANT(size_type, npos = static_cast<size_type>(-1));
explicit dynamic_bitset(); //显式的无参构造函数,拒绝隐式调用
dynamic_bitset(const dynamic_bitset& b);
void swap(dynamic_bitset& b); //基本操作集合
void resize(size_type num_bits, bool value = false);
void clear();
void push_back(bool bit);
void append( Block block);
//注意因为dynamic_bitset也并非严格意义上的容器,故而也没有begin()和end()迭代器遍历接口
bool operator[](size_type pos) const; //操作符[]重载
dynamic_bitset& operator&=(const dynamic_bitset& b);
dynamic_bitset& operator|=(const dynamic_bitset& b);
...
dynamic_bitset& set(); //bit翻转
dynamic_bitset& reset();
dynamic_bitset& flip(); //位图取反
bool test(size_type n) const; //bit测试
bool any() const; //检测位图,若有任意1,则返回true
bool none() const; //检测位图,若有任意1,则返回false
dynamic_bitset operator~() const; //重载取反符号
size_type count() const; //检测位图中有1的数目
unsigned long to_ulong() const; //转型到ulong
size_type size() const;
size_type num_blocks() const;
size_type max_size() const;
bool empty() const;
bool is_subset_of(const dynamic_bitset& a) const; //集合操作
bool is_proper_subset_of(const dynamic_bitset& a) const;
size_type find_first() const;
size_type find_next(size_type pos) const;
*/
#include <iostream>
#include <string>
#include <boost/dynamic_bitset.hpp>
#include <boost/utility.hpp> //定义了BOOST_BINARY宏
using namespace std;
using namespace boost;
int main()
{
dynamic_bitset<> db1;
dynamic_bitset<> db2(10);
dynamic_bitset<> db3(0x16,
BOOST_BINARY(10101));
//大小为22,并采用boost的编译器宏BOOST_BINARY在编译器直接创建一个二进制数,没有运行时开销
dynamic_bitset<> db4(string("0100"));//使用string构建临时对象,存在运行期开销
dynamic_bitset<> db5(db3);
dynamic_bitset<> db6;
db6 = db4;
cout << hex << db5.to_ulong() << endl; //转换为整数, 0x15 = 21
cout << db4[0] << db4[1] << db4[2] << endl; //dynamic_bitset从高到低存储二进制位,即[0]对应最低位
cout << db2 << endl;
cout << db6 << endl;
//“容器”操作
cout << "*****************size-related operation resize/size/clear" << endl;
db2.resize(20, true); //扩展
cout << db2 << endl;
db2.resize(15); //收缩
cout << db2 << endl;
db2.clear(); //清空
cout << "db2:" << db2 << endl;
assert(db2.size() == 0 && db2.empty() ); //判断db2是否为空
//判断一个dynamic_bitset占据了几个block,如果block是默认的unsigned long,则对应为8*8即64个字节
//assert(dynamic_bitset<>(64).num_blocks() == 2);
assert(dynamic_bitset<>(65).num_blocks() == 3);
cout << dynamic_bitset<>(64).num_blocks() << endl; //2
cout << sizeof(unsigned long) << endl; //4
cout << db6 << endl; //0100
cout << db6.size() << endl; //4
db6.append(BOOST_BINARY(101));
cout << db6 << endl; //000000000000000000000000000000001010100
cout << db6.size() << endl; //24
//位运算操作,使用了代理技术,存在class class的内部类,用以完成细粒度元素的位运算
cout << "*****************bit-op operation ^/&/|" << endl;
dynamic_bitset<> db7(4, BOOST_BINARY(1010));
db7[0] &= 1; //与
db7[1] ^= 1; //异或
cout << db7 << endl; //1000
dynamic_bitset<> db8(4, BOOST_BINARY(0101));
assert(db7 > db8 );
cout << (db7 ^ db8) << endl; //1101
cout << (db7 | db8) << endl; //1101
cout << (db7 & db8) << endl; //0000
//返回元素
cout << "*****************statistical operation test/any/none/count" << endl;
cout << db8.test(0) << endl; //查看二进制数的第n位是否为1 //1
cout << db8.any() << endl; //查看二进制数是否有任意1 //1
cout << db8.none() << endl; //any的反操作 //0
cout << db8.count() << endl; //统计db8中所有值为1的元素的数量 //2
cout << db8.find_first() << endl; //从第0位置开始查找,返回第一个值为1的位置
cout << db8.find_next(0) << endl; //从第n位置开始查找,返回第一个值为1的位置,若找不到则返回npos
cout << "*****************reverse operation set/reset/flip" << endl;
cout << db8 << endl; //0101
db8.set(); //可以置全部或特定位置为1或0,默认是1
cout << db8 << endl; //1111
db8.reset(); //可以置全部或特定为0
cout << db8 << endl; //0000
db8.flip();//将特定位置或全部位置翻转
cout << db8 << endl; //1111
cout << "*****************type conversion to_ulong/to_string" << endl;
cout << std::dec << db8.to_ulong() << endl;
string str;
to_string(db8, str);
cout << str << endl;
cout << "*****************list operation is_subset_of/is_proper_subset_of" << endl;
dynamic_bitset<> db9(4, BOOST_BINARY(11)); //即便是做子集判断,依旧要求两个dynamic_bitset的size是等价的
dynamic_bitset<> db10(db8);
assert(db9.is_proper_subset_of(db8)); //真子集
assert(db10.is_subset_of(db8)); //子集
cout << "*****************a demo for selecting prime number" << endl;
int n;
cin >> n;
dynamic_bitset<> db(n); //初始化为size=n,全部位置为1
db.set(); //翻转,全部置为1
for (dynamic_bitset<>::size_type i = db.find_next(1);
i != dynamic_bitset<>::npos;
i = db.find_next(i) ) //因为dynamic_bitset不是标准容器,所以不能使用迭代器,也不能用for+auto范围迭代
{
for (dynamic_bitset<>::size_type j = db.find_next(i);
j != dynamic_bitset<>::npos;
j = db.find_next(j))
{
if (j % i == 0)
{
db[j] = 0;
}
}
}
for (dynamic_bitset<>::size_type i = db.find_next(2);
i != dynamic_bitset<>::npos;
i = db.find_next(i))
{
cout << i << ", ";
} //如输入10,则打印: 3, 5, 7,
return 0;
}
Boost (2): dynamic_bitset二进制数
最新推荐文章于 2024-06-20 11:08:42 发布