按位与、或、非、异或总结
原文链接:https://blog.csdn.net/weixin_42216574/article/details/82885102
二进制中1的个数
给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 1 的个数。
输入格式
第一行包含整数 n。
第二行包含 n 个整数,表示整个数列。
输出格式
共一行,包含 n 个整数,其中的第 i 个数表示数列中的第 i 个数的二进制表示中 1 的个数。
数据范围
1≤n≤100000,
0≤数列中元素的值≤1e9
输入样例:
5
1 2 3 4 5
输出样例:
1 1 2 1 2
#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
cin>>n;
while(n--){
int res=0;
int x;
cin>>x;
while(x){
x-=x&(-x);
res++;
}
cout<<res<<" ";
}
return 0;
}
二进制中1的个数
输入一个 32 位整数,输出该数二进制表示中 1 的个数。
注意:
- 负数在计算机中用其绝对值的补码来表示。
数据范围
−100≤ 输入整数 ≤100
样例1
输入:9
输出:2
解释:9的二进制表示是1001,一共有2个1。
样例2
输入:-2
输出:31
解释:-2在计算机里会被表示成11111111111111111111111111111110,
一共有31个1。
方法1:
上面这道题统计的是正整数中二进制1的个数, 但是如果数据是负数,那就会wa,必须强制转化成无符号类型:
class Solution {
public:
int NumberOf1(int n) {
int res = 0;
unsigned un = n;
while(un){
if(un & 1) res ++;
un >>= 1;
}
return res;
}
};
方法2:
class Solution {
public:
int NumberOf1(int n) {
int res = 0;
while(n){
n-=n&(-n);
res++;
}
return res;
}
};
统计非负整数二进制展开中数位1的总数
统计非负整数二进制展开中数位1的总数。如整数64 的二进制展开为00000000 00000000 00000000 00100000 ,数位1的总数为1。
输入格式:
输入一个整数n , 题目保证n 不大于 10的18次方。
输出格式:
输出该整数二进制展开中数位1的总数。
输入样例:
在这里给出一组输入。例如:
441
输出样例:
在这里给出相应的输出。例如:
6
//法 1 :
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,res=0;
int main(){
cin>>n;
while(n){
n-=n&(-n);
res++;
}
cout<<res<<endl;
return 0;
}
//法 2 :
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,res=0;
int main(){
cin>>n;
while(n){
res++;
n&=(n-1);
}
cout<<res;
return 0;
}
//法 3 :
#include<bits/stdc++.h>
#define ll long long
const int N=1e18+10;
using namespace std;
int main(){
ll n,x=1;
int cnt=0;
cin>>n;
while(n){
x*=2;
if(x>n){
n=n-x/2;
cnt++;
x=1;
}
}
cout<<cnt<<endl;
return 0;
}
位运算 考点:
求 n 的第 k 位数字: n >> k &1
返回 n 的最后一位 1 : lowbit ( n )= n &-n
lowbit的作用是返回x的最后(右)一位 1
x= 1010 lowbit(x)=10;
x= 101000 lowbit(x)=1000
x& -x=x&(~x+1)
-x=~x+1
x&(~x+1)=0000001 (最后一位1)
应用:统计 x 里面 1 的个数
x & (x - 1) 就是把最低位的1去掉
源码: 000.....01010
反码: 111......10101
补码: 111......10110(~x+1)
计算机底层实现没有减法,要用加法作减法 [x + ( -x ) = 0]