(C++) stl之bitset 使用小结


bitset是一个特殊有的stl容器,顾名思义bitset是对位比特的操作,这里专指位运算操作

头文件

#include <bitset>
#include <bits/stdc++.h>

定义

debug()定义

#define debug(x) cout<<#x<<" = "<<x<<endl

通常的stl在尖括号<type>中是类型

<len>这里是长度,且必须是常量

明确一点: bitset 的二进制是 从右往左 看的

定义的长度足够

多余的位数补前导0

数值型参数是:unsigned long val 所以如果用负数可能会出错

    // 无值默认全0
    bitset<10> bs1;
    debug(bs1);

    // 长度必须是常量
    const int len = 10;
    bitset<len> bs2;
    debug(bs2);

    // 同类型赋值
    bitset<10> bs3 = bs1;
    bs3 = bs1;
    debug(bs3);
    
    //  数值法  等号法 括号法均可
//    bitset<10> bsByNumber(123);
    bitset<10> bsByNumber = 123;
//    bitset<10> bsByNumber('a');
    debug(bsByNumber);
    
	// 字符串法 不可以用等号法
    bitset<10> bsByString("10101");
    debug(bsByString);

    string s = "1111111111";
    bitset<10> bsBySubstring(s,0, 5);
    debug(bsBySubstring);

输出:

bs1 = 0000000000
bs2 = 0000000000
bs3 = 0000000000
bsByNumber = 0001111011
bsByString = 0000010101
bsBySubstring = 0000011111

定义的长度不够

数值 从右往左保留

字符串 从左往右保留

    bitset<5> bsString("1011111001");
    debug(bsString);

    // 123 的二进制 1111011
    bitset<5> bsNumber(123);
    debug(bsNumber);

	// 不能resize
	bs.resize(10);

输出:

bsString = 10111
bsNumber = 11011

注意点

读取到非01字符编译不报错,运行报错

bitset<5> bsString("101asd");

terminate called after throwing an instance of 'std::invalid_argument' what(): bitset::_M_copy_from_ptr

看下占位多大

    bitset<10> bs(123);
    cout << "sizeof bs = " << sizeof bs << endl;
    cout << "sizeof bs[0] = " << sizeof bs[0] << endl;

输出:

sizeof bs = 4
sizeof bs[0] = 16

注意每一个bitset的数值均是unsigned long

操作符

!=, ==, &=, ^=, |=, ~, <<=, >>=, []

除最后一个和[]操作符,其余均是对于bitset整体的操作,但是其长度len必须相同

    bitset<10> bs(123);
    debug(bs);
	// 从右往左
    for (int i = 0; i < 10; i++){
        cout << bs[i] << " \n"[i == 10-1];
    }

输出:

bs = 0001111011
1 1 0 1 1 1 1 0 0 0

方法/函数

to_string()

正所谓世间万物均可二进制字符串

这里的to_string 和我们平时将数值型转为字符串的并不相同,这是是bitset的内置方法

    bitset<10> bs(123);
    debug(bs);


    string s = bs.to_string();
    debug(s);

//    s = to_string(bs);

输出:

bs = 0001111011
s = 0001111011

to_ulong()/to_ullong()

转为整形

    bitset<10> bs(123);
    int num = bs.to_ullong();
    unsigned long longNum = bs.to_ulong();
    unsigned long long longlongNum = bs.to_ullong();
    debug(bs);
    debug(num);
    debug(longNum);
    debug(longlongNum);

输出:

bs = 0001111011
num = 123
longNum = 123
longlongNum = 123

size()

返回定义时的容量大小

any()/none()

any() 是否存在1

none() 是否不存在1

    bitset<5> bs(1);
    debug(bs);

    if (bs.any()) {
        cout << "存在1" << endl;
    }
    if (bs.none()) {
        cout << "不存在1" << endl;
    }

    bs = 0;
    debug(bs);

    if (bs.any()) {
        cout << "存在1" << endl;
    }
    if (bs.none()) {
        cout << "不存在1" << endl;
    }

输出:

bs = 00001
存在1
bs = 00000
不存在1

test()

判断第idx位是否是1

    bitset<10> bs(123);
    debug(bs);

    if (bs.test(0)) {
        cout << "第0位是 1" << endl;
    }
    if (bs.test(bs.size()-1)) {
        cout << "第bs.size()-1位是 1" << endl;
    }

输出:

注意:此处位数从后往前数

bs = 0001111011
第0位是 1

count()

返回1的个数

    bitset<10> bs(123);
    debug(bs);
    debug(bs.count());

输出:

bs = 0001111011
bs.count() = 6

flip()

按位取反

    bitset<10> bs(123);
    debug(bs);
    // 无参全部反置
    bs.flip();
    debug(bs);

    // 指定第几位反置
    bs.flip(0);
    debug(bs);
    // 效果相同
    bs[0] = ~bs[0];
    debug(bs);

输出:

bs = 0001111011
bs = 1110000100
bs = 1110000101
bs = 1110000100

reset()

按位置0

    bitset<10> bs(123);
    debug(bs);

    // 指定位置置0
    bs.reset(0);
    debug(bs);

    // 全部置0
    bs.reset();
    debug(bs);

输出:

bs = 0001111011
bs = 0001111010
bs = 0000000000

set()

按位置1(默认)

也可以指定位置置0

    bitset<10> bs(124);
    debug(bs);

    // 指定位置置1
    bs.set(0);
    debug(bs);

    // 全部置1
    bs.set();
    debug(bs);

    // 也可以指定位置置0
    bs.set(0, 0);
    debug(bs);

输出:

bs = 0001111100
bs = 0001111101
bs = 1111111111
bs = 1111111110

其实bitset还有很多方法,此处只列举一些常用的




END

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值