位运算
与& | 0&0=0 | 1&0=0 | 0&1=0 | 1&1=1 |
或| | 0|0=0 | 1|0=1 | 0|1=1 | 1|1=1 |
异或^ | 0^0=0 | 1^0=1 | 0^1=1 | 1^1=0 |
题目:
实现一个函数,输入一个整数,输出该数的二进制表示中1的个数,例如9的二进制是1001,有两个1,输入9,输出1
程序1.0
写法1:模除法 int CountOne(int n) { int count = 0; while (n) { int ret = 0; ret = n % 2; if (1 == ret) count++; n /= 2; } return count; }
程序2.0
位运算,由于除法的效率要远远低于位运算,所以在需要用乘除时尽量用位运算代替
而右移运算符又会引入一个新问题,若输入一个负数,则会导致无限循环(右移时左边补符号位)
int CountOne(int n) { int count = 0; while (n) { if ((n & 1) == 1) { count++; } n=n >> 1; } return count; }
算法2.1
位运算改进,不对输入的数进行移位
int CountOne(int n) { int count = 0; size_t flag = 1; while (flag) { if (n&flag) count++; flag <<= 1; } return count; }
算法3.0
把一个整数减去1,再和原整数做与运算,会把该整数的最右边的一个1变成0,那么一个整数的二进制表示中有多少个1,就可以做多少次这样的操作
int CountOne(int n) { int count = 0; while (n) { ++count; n = (n - 1)&n; } return count; }
*把一个整数减去1再和原来的整数做位与运算得到的结果相当于把这个整数中表示最右边的一个1变成0
举一反二
- 用一条语句判断一个整数是不是2的整数次方,一个整数如果是2的整数次方那么它的二进制表示中有且仅有一位是1,其他位都是0;
分析:这个数减去1再和自己位与,这个整数中唯一的1就会变成0
2. 输入两个整数n和m,计算需要改变m的二进制表示中的多少位才能得到n,比如10的二进制位1010,13的二进制1101,需要1010改变3位才能得到1101,
分析:第一步求这两个数的异或,第二部统计异或结果中1的位数
时间: 2024-10-07 14:20:51