到这里第二章就结束了,之后的题目我将会以章的结构来统一撰写博客,毕竟一篇一篇地写意义不太高
1.考点
- 考点1:二进制的运用:与&,或|,异或^三种运算符的巧用;
- 考点2:对于正负数的二进制理解:32位系统,共有0-31共32位的数据,其中第31位为符号位,正数为0负数为1,所以正数的int范围为(1,231-1),负数的int范围为(-231,-1);
- 考点3:对于正负数的计算机表述:原码反码与补码,正数的三码相同,负数的原码正常,反码为原码的按位取反,补码为反码+1,所以正数的边界为(0x00000001,0x7FFFFFFF),负数的边界为(0x8000000,0xFFFFFFFF),这些边界都是十六进制的存储方式(十六进制用最高位作为符号位,1为负数,0为正数,后面的数字都是序号,而负数的第一位为-231,而正数的第一位就是1),所以负数的值会看起来比较奇怪;
- 考点3:n = (n-1)&n,这样可以实现将n中最右边的1置为0,非常好用
2.代码
- 两种实现方式,其中第二种方式确实更易于操作,循环次数少的多
#include <iostream>
using namespace std;
class Solution
{
public:
//1.常规解法,考虑到整数的正负情况,选择左移标志位,而不是右移源数据
//牛客网:运行时间:5ms,占用内存:376k
int NumberOf1(int n)
{
int count = 0;
int flag = 1;
while (flag)
{
//逐位判断n中的当前位置是否为1,是则+1
if (flag & n)
count++;
flag <<= 1;
}
return count;
}
//2.思想解法:(n-1)&n,即可将n最右边的1去掉,通过不断地去1直到n为0(速度比上一种快,因为可以定点删1)
//牛客网 运行时间:3ms,占用内存:480k
int NumberOf2(int n)
{
int count = 0;
while (n)
{
count++;
n = (n - 1)&n;
}
return count;
}
};