1. 位图解决某一范围上数字的出现情况,节省大量时间
- 题目分析
使用哈希方法进行求解,常规思路为申请一个哈希表,将文件中每一个数字经过哈希函数以后的哈希值放进对应的哈希格子(哈希表相应的位置值加一);这样将文件中的所有数字都遍历一遍以后,观察 哈希表,哈希表中元素为0的位置对应的数字就是没有出现的数字;
但是这样的话,就需要申请一个长度为232的哈希表,每个位置都为无符号整型的类型uint(4个字节,32位,范围为0 ~ 232-1,可以满足文件中所有数字相同的请情况);这样的话限制内存10M,一定不够用的;更别说限制内存10kB;
假如限制内存3KB,那么3KB=3000byte,3000/4 = 750个无符号整型;所以申请长度为512的哈希表;将0 ~ 232的数据分为512份,然后遍历文件中的数据,将对应哈希表位置元素加1;当文件中的数字遍历结束后,观察哈希表每个位置元素大小,找出没有达到232 / 512 的位置,这说明512份数据中,这部分的数据出现了缺失,我们寻找的缺失数据一定在这部分;接着再一次遍历文件元素,不在这部分的数字忽略,在这部分的数字按重新的512块原则存放;依次操作下去,就可以在3KB的内存上完成;
2. 位运算求最大值
位运算比较两个数中的最大值
- 思路1
- code
int flip(int n)
{
return n ^ 1;
}
int sign(int n)
{
return flip((n >> 31) & 1);
}
int get_max1(int a, int b)
{
int c = a - b;
int scA = sign(c);//a-b为非负,scA=1;a-b为负,scA=0
int scB = flip(scA);// a - b为非负,scB = 0; a - b为负,scB = 1
return a * scA + b * scB;
}
思路1问题:当a-b溢出的时候,结果就不对了
- 思路2
- code2
int get_max2(int a, int b)
{
int c = a - b;
int sa = sign(a);//a为非负,sa = 1;
int sb = sign(b);//b为非负,sa = 1
int sc = sign(c);
int difSab = sa ^ sb; //a和b符号不同,difSab =1;
int samSab = flip(difSab);//a和b符号相同,samSab =1;
int returnA = difSab * sa + samSab * sc;//a,b符号相同且a>b 或者
//a,b符号不同且a>0的时候返回A
int returnB = flip(returnA);
return a * returnA + b * returnB;
}
疑问:怎么确定a,b符号不同时,a>0的时候,sign©为1
3. 判断一个整数是否为2的幂
-
思路1
如果判断一个数组是2的n次幂;那么就将数字右移n位,判断此时的末尾是否位1,如果是1,就说明是2的n次幂 -
思路2
数字如果位2的幂,那么二进制形式中只有一个1;
如果x&(x-1)=0,那么x就是2的幂; -
code
bool is4pow(int n)
{
return (n&(n-1))==0;
}
4. 判断一个整数是否为4的幂
- 判断X是否为2的幂,即二进制形式中只有一个1
2)如果X为2的幂,就需要进一步判断X是否为4的幂
如果X为4的幂,二进制形式中,可能在第0,2,4,6,8等偶数上只有一个1,奇数位上没有一个1;X&(0101010101…0101)!=0,说明X为4的幂
- code
bool is4pow(int n)
{
return (n&(n-1))==0 & (n&0x5555)!=0;
}
使用位运算完成两个数的加减乘除
https://www.bilibili.com/video/BV13g41157hK?p=16
一小时40分