1、n&1的含义
以10为例子:
0 1010
& 0001
————————————
0 0000
以15为例子:
0 1111
& 0001
————————————
0 0001
因此n&1,返回的是”n 二进制最右一位是0还是1“
#include<iostream>
using namespace std;
//n&1:与操作,判断 n 二进制最右一位是否为 1
void g() {
int n;
cin >> n;
int x = n & 1;
cout << x << endl;
}
int main(){
g();
}
2、n >> k & 1的含义
以10为例,10的二进制为1010,右移0位为1010;右移1位为0101,右移2位为0010,右移3位为0001.
0 1010 0 0101 0 0010 0 0001
& 0001 & 0001 & 0001 & 0001
——— ——— ——— ———
0 0000 0 0001 0 0000 0 0001
因此,可以得到第0位-第3位为分别为0101
位数: 43210
每位上的数字: 01010
因此,n >> k & 1返回的是”n的第k位数字“
#include<iostream>
using namespace std;
//n >> k & 1:求n的第k位数字
void h(){
int n=15;
//输出15的每一位上的数字
for(int i=3;i>=0;i--){
cout<<(n >> i & 1)<<" ";
}
}
int main(){
h();
}
3、lowbit(n) = n & -n的含义
假设n的二进制码为1010… …100…0
n & -n 等价于 n & (~n+1) 即源码&补码(源码取反码+1)
n = 1010… …100…0
~n = 0101… …011…1
~n+1 = 0101… …100…0
01010… …100…0
&0101… …100…0
————————————
00000… …100…0
即lowbit(n)的二进制码为100…0。因此lowbit(n) = n & -n的返回的是“n二进制最右一位1及其后面的所有位”
4、二进制中1的个数
以下题目是利用二进制位运算的一个实际应用例子,利用lowbit(n) = n & -n的返回的是“n二进制最右一位1及其后面的所有位”的特性,将n-=lowbit(n),每次消除n的最右位1,从而计算一个数二进制中1的个数。
//二进制中1的个数
#include<iostream>
using namespace std;
const int N = 100010;
int a[N];
//lowbit操作返回“截取一个数字最后一个1后面的所有位”的数字
int lowbit(int x) {
//x&~x+1 源码&补码(源码取反码+1)
return x & -x;
}
int main() {
int n;
cin >> n;
//输入序列
for (int i = 0; i < n; i++) {
cin >> a[i];
}
//求每个数二进制中1的个数
for (int i = 0; i < n; i++) {
int one_num=0;
int x=a[i];
while (x) {
x -= lowbit(x);
one_num++;
}
cout << one_num<<" " ;
}
}