【位运算】二进制中1的个数及其变种

版权声明:本文为博主原创学习笔记,如需转载请注明来源。 https://blog.csdn.net/SHU15121856/article/details/82388007

位运算

C++里面的与、或、异或、按位取反分别是&|^~符号。左移运算是<<,左移后右边补n个0。右移运算是>>,正数右移在左边补n个0,负数右移在左边补n个1。

二进制中1的个数

输出一个整数的二进制形式中1的个数。

可能引起死循环的解法
#include<bits/stdc++.h>
using namespace std;

//可能引起死循环的解法
int NumberOf1_Solution0(int n) {
    int count=0;//计数
    //只要n还不是0 
    while(n){
        if(n & 1)//如果n和1相与为1,即最低位为1
            count++;//记录一下
        n=n>>1;//右移一位把最低位挤掉
        //当是负数时,显然最左边会补1,这时候就停不下来了 
    }
    return count;
}

int main(){
    cout<<NumberOf1_Solution0(9)<<endl;
    return 0;
}
常规解法
#include<bits/stdc++.h>
using namespace std;

//常规解法 
int NumberOf1_Solution1(int n) {
    int count = 0;//计1的个数
    unsigned int flag = 1;//要测试某一位是否为1的测试值,初始测试最低位,所以用1
    //当左移没有超过二进制位数 
    while (flag) {
        //用测试值和数字相与,可以测试相应的位 
        if (n & flag)//相与为1,则那一位为1 
            count++;//记录之 
        flag = flag << 1;//测试值左移 
    }
    //循环的次数等于整数二进制的位数,左移超过了最高位就自然变0退出循环了 
    return count;
}

int main(){
    cout<<NumberOf1_Solution1(9)<<endl;
    return 0;
}
能给面试官带来惊喜的解法

一个整数减去1,可以将其最右边第一个1一直到最右边为止的所有数位取反。如:

1011 1 = 1010

1100 1 = 1001

利用这个性质,原数和减去1之后的数做与运算,则可以去掉原数最右边的一个1,有多少个1就可以做多少次这样的运算。

#include<bits/stdc++.h>
using namespace std;

//能给面试官带来惊喜的解法 
int NumberOf1_Solution2(int n) {
    int count = 0;//计数 
    //循环直到数字中所有1全没了,就变成0结束 
    while (n) {
        ++count;//记录这个1 
        n = (n - 1) & n;//去掉这个最右边的1 
    }
    return count;
}

int main() {
    cout<<NumberOf1_Solution2(9)<<endl;
    return 0;
}

相关题目

用一条语句判断一个整数是不是2的整数次方

二的整数次方中有且只有一个1,经一次上面的运算后势必变成0。

#include<bits/stdc++.h>
using namespace std;

bool is2Power(int n){
    return !(n&(n-1));//注意'!'的优先级最高,要把里面东西括起来 
}

int main(){
    cout<<boolalpha<<is2Power(8)<<endl;
    cout<<boolalpha<<is2Power(9)<<endl;
    return 0;
}
计算m需要改变多少位才能变成n

先异或,就将不同的位标记成了1,再计算异或结果中1的个数。

#include<bits/stdc++.h>
using namespace std;

int howManyTransfer(int m,int n){
    int k=m^n;//异或结果中将不同为标记成了1
    //计算异或结果中1的个数
    int count=0;
    while(k){
        k=k&(k-1);
        count++;
    } 
    return count;
}

int main(){
    cout<<howManyTransfer(8,9)<<endl;
    cout<<howManyTransfer(13,10)<<endl;
    cout<<howManyTransfer(11,-1)<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/SHU15121856/article/details/82388007