c++ bitset总结
C++的 bitset 在 bitset 头文件中,bitset大概就是类似于bool数组一样的东西。但是它的每个位置只占1bit(特别特别小)
一般来说bitset会让你的算法复杂度下降很多
1.初始化
//初始化
bitset<24>bit;//bitset类型在定义时就需要指定所占的空间,默认全为0
//bitset类型可以用string和整数初始化(整数转化成对应的二进制),不足位数时会自动在前面补0
bitset<23>bit(string("11101001"));
cout<<bit<<endl;//输出00000000000000011101001
bitset<23>bit(233);
cout<<bit<<endl;输出00000000000000011101001
//用字符串构造时,字符串只能包含 '0' 或 '1' ,否则会抛出异常。
//在进行有参构造时,若参数的二进制表示比bitset的size小,则在前面用0补充(如上面的栗子);若比bitsize大,参数为整数时取后面部分,参数为字符串时取前面部分
bitset<2> bitset1(12); //12的二进制为1100(长度为4),但bitset1的size=2,只取后面部分,即00
string s = "100101";
bitset<4> bitset2(s); //s的size=6,而bitset的size=4,只取前面部分,即1001
char s2[] = "11101";
bitset<4> bitset3(s2); //与bitset2同理,只取前面部分,即1110
cout << bitset1 << endl; //00
cout << bitset2 << endl; //1001
cout << bitset3 << endl; //1110
2.位运算
//bitset支持所有位运算
bitset<23>bita(string("11101001"));
bitset<23>bitb(string("11101000"));
cout<<(bita^bitb)<<endl;//输出00000000000000000000001
cout<<(bita|bitb)<<endl;//输出00000000000000011101001
cout<<(bita&bitb)<<endl;//输出00000000000000011101000
cout<<(bita<<5)<<endl;//输出00000000001110100100000
cout<<(bita>>5)<<endl;//输出00000000000000000000111
3.常用函数
//对于一个叫做bit的bitset:
bit.size() 返回大小(位数)
bit.count() 返回1的个数
bit.any() 返回是否有1
bit.none() 返回是否没有1
bit.set() 全都变成1
bit.set(p) 将第p + 1位变成1(bitset是从第0位开始的!)
bit.set(p, x) 将第p + 1位变成x
bit.reset() 全都变成0
bit.reset(p) 将第p + 1位变成0
bit.flip() 全都取反
bit.flip(p) 将第p + 1位取反
bit.to_ulong() 返回它转换为unsigned long的结果,如果超出范围则报错
bit.to_ullong() 返回它转换为unsigned long long的结果,如果超出范围则报错
bit.to_string() 返回它转换为string的结果
4.使用技巧
一般用来优化奇偶性有关的问题,或者判断联通性之类的,(还可以在搜索的时候优化访问标记)
如力扣5852题:
class Solution {
public:
int minimizeTheDifference(vector<vector<int>>& A, int target) {
int n=A.size();
int m=A[0].size();
bitset<5000> F[n];//设立一个bitset数组,标记到达每一行时能拼凑出的数
F[0]=0;
for (int i=0;i<m;++i) F[0][A[0][i]]=1;//矩阵第一行直接标记
for (int i=1;i<n;++i)
{
F[i]=0;
for (int j=0;j<m;++j) {
F[i] |= F[i - 1] << A[i][j];//先移位,一次完成矩阵上一行加下一行某个数的计算。再异或,传递到bitset数组对应的当前行记录
}
}
int ans=4900;//最大4900,题目限制
for (int i=1;i<=4900;++i)
if (F[n-1][i])
ans=min(ans,abs(target-i));
return ans;
}
};
假如不使用bitset,类似的标记思路,但是复杂度更高
class Solution {
public:
int minimizeTheDifference(vector<vector<int>> &mat, int target) {
int s = 0;
for (auto &v : mat) s += *max_element(v.begin(), v.end());
vector<int> dp(s + 1);
dp[0] = 1;
for (auto &v : mat) {
vector<int> nxt(s + 1);
for (int x : v)
for (int i = x; i <= s; i += 1)//上一个算法的移位操作也大大减少了复杂度
if (dp[i - x]) nxt[i] = 1;
dp.swap(nxt);
}
int ans = abs(s - target);
for (int i = 0; i <= s; i += 1)
if (dp[i]) ans = min(ans, abs(i - target));
return ans;
}
};