关于C++STL刷题知识点汇总文章可以参考:
C++刷题基础知识(栈、队列、hash、STL、基础函数等)---持续更新-CSDN博客
一、位运算
位运算主要是将int的二进制表示进行比较,算法题中常有的给定整数值进行二进制统计。
1.1 位运算操作表格
位运算操作 | 描述 | 示例(假设操作数为二进制数) |
---|---|---|
按位与(&) | 将两个操作数的每个位进行比较,如果两个操作数的相应位都为1,则结果为1,否则为0。 | 1010 & 0110 = 0010(二进制) |
按位或(|) | 将两个操作数的每个位进行比较,如果两个操作数的相应位中有至少一个为1,则结果为1,否则为0。 | 1010 | 0110 = 1110(二进制) |
按位异或(^) | 将两个操作数的每个位进行比较,如果两个操作数的相应位不同,则结果为1,否则为0。 | 1010 ^ 0110 = 1100(二进制) |
按位取反(~) | 将操作数的每个位取反,即0变为1,1变为0。 | ~1010 = 0101(二进制) |
左移(<<) | 将操作数的所有位向左移动指定的位数,右侧用0填充。 | 1010 << 2 = 101000(二进制) |
右移(>>) | 将操作数的所有位向右移动指定的位数,左侧用0填充。 | 1010 >> 2 = 0010(二进制) |
1.2 位运算操作代码
#include <iostream>
using namespace std;
int main() {
int a = 60; // 60 = 0011 1100
int b = 13; // 13 = 0000 1101
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "a & b = " << (a & b) << endl; // 12 = 0000 1100
cout << "a | b = " << (a | b) << endl; // 61 = 0011 1101
cout << "a ^ b = " << (a ^ b) << endl; // 49 = 0011 0001
cout << "~a = " << (~a) << endl; // -61 = 1100 0011
cout << "a << 2 = " << (a << 2) << endl; // 240 = 1111 0000
cout << "a >> 2 = " << (a >> 2) << endl; // 15 = 0000 1111
return 0;
}
1.3 位运算的一些技巧算法
1.判断一个int类型存在多少个bit=1的位数,可以采用常规的暴力方式,也可以采用Brian Kernighan算法;
- 暴力求解:通过不断地左移bit与1进行相与比较;n&1;n>>1;
-
Brian Kernighan 算法:对于任意整数 x,令 x=x & (x−1),该运算将 x 的二进制表示的最后一个 1变成 0。因此,对 x 重复该操作,直到 x 变成 0,则操作次数即为 x 的「一比特数」。每一次的x-1都会使32进制表示的bit位中最后一个1翻转为0;
//1.常规右移
cont+=n & 1;
n=n>>1;
//2.依次最低位
x &= (x - 1);//x=111000 x-1=110111 x & (x - 1)=110000
2.最高有效位,当上面的Brian Kernighan 算法存在如下的特殊形式时表明该比特为最高有效位;
(x & (x - 1)) == 0//100000 011111
关于C++STL刷题知识点汇总文章可以参考: