位运算的常见操作符:
按位与:A&B 只有A,B对应的二进制位上数同时为1,A&B 对应的二进制该位数为1.
按位或:A|B 只有A,B对应的二进制位上数有一个为1,A&B 对应的二进制该位数为1.
按位异或:A^B 相同两个数做异或 对应二进制上所有位位置上值为零。
取反:~
左移右侧补零:<<
右移左侧补符号位:>>
右移左侧补零:>>>
1.从一个数组中找出一个只出现一次的数,其余都出现过三次
思路:
记录数组上所有数对应不同位上的值的和,然后可以得到32 个和(int整数只有32 位)
如果一个数出现三次,则对应的32个不同位数和 分别%3操作 值都为0.,所以对上述对应的32 个和分别进行%3操作 得到的其实就是只出现一次的那个数的所有二进制位上值。
public static int singleNumber(int[] A) {
int res=0;
for(int i=0;i<32;i++) {
int sum=0;
for(int j=0;j<A.length;j++) {
//ATTention:A[j]>>i 移位后 必须与 1 进行与 运算猜得到最优一位上的值。
sum+= (A[j]>>i) & 1;
System.out.printf("%d ",A[j]>>i);
System.out.println();
}
res |=(sum%3)<<i;
}
return res;
}
2.寻找奇数出现:有一个整形数组A,只有一个数出现奇数次,其他出现偶数次,打印这个数:
A^A=0;0^A=A.
class OddAppearance {
public:
int findOdd(vector<int> A, int n)
{
int temp=0;
for(int i=0;i<n;i++)
temp=temp^A[i];
return temp;
}
};
网页黑名单系统,垃圾邮件过滤系统,容忍失误率对空间要求严格。布隆过滤器。
布隆过滤器:精确代表一个集合,使用很少的空间。布隆过滤器的bitarray的大小m根据样本数量n,失误率p. m=20n.
不使用额外变量交换两个整数值:
a=a0,b=b0;
a=a^b;—->a=a0^b0 , b=b0;
b=a^b;—->a= a0^b0 ,b=a0;
a=a^b;—-
不通过比较判断两个整数大小:
方法一:得到a-b 符号
class Compare {
public:
int Flip(int c)
{
return c^1;
}
int GetSign(int c)
//非负为1,负为0.
{
return Flip((c>>31)&1);
}
int getMax(int a, int b)
{
int c=a-b;
int as=GetSign(a);
int bs=GetSign(b);
int cs=GetSign(c);
int sam=Flip(as^bs);
if(sam)
return cs?a:b;
else
return (as-bs)?a:b;
}
};