方法1.
x & (x - 1) 用于消去x最后一位的1
x = 1100
x - 1 = 1011
x & (x - 1) = 1000
例题:
计算在一个 32 位的整数的二进制表式中有多少个 1。
由x & (x - 1)消去x最后一位的1可知。不断使用 x & (x - 1) 消去x最后一位的1,计算总共消去了多少次即可。
用来计算Power of 2:
比如说3. =0011。 去掉最后一个1以后变成0010.不等于0,所以这个不是power of 2.
原理:是power of 2的: 1, 2,4,8, 16,32...都是只有一个1在里面:10000。
难例题:
如果要将整数A转换为B,需要改变多少个bit位?
思考将整数A转换为B,如果A和B在第i(0<=i<32)个位上相等,则不需要改变这个BIT位,
如果在第i位上不相等,则需要改变这个BIT位。所以问题转化为了A和B有多少个
BIT位不相同。联想到位运算有一个异或操作,相同为0,相异为1,所以问题转变成了
计算A异或B之后这个数中1的个数。
方法2:
a ^ b ^ b = a
b^b = 0 因为xor是相同为0,不相同为1
a ^ 0 = a 因为a 如果是0,0 ^ 0 =0, a如果是1, 1^0 =1
方法3:
return itself:
bit ^ 0
inverse itself:
bit ^ 1
Single Number 例题:
数组中,只有一个数出现一次,剩下都出现两次,找出出现一次的数
因为只有一个数恰好出现一个,剩下的都出现过两次,所以只要将所有的数异或起来,就可以得到唯一的那个数。
假设数=abcdefg 字母表示digit
a ^ b ^ c ^ d ^ e ^ f ^ g 因为出现两次的会消除掉,所以可以得到那个single number。
Single Number升级版:
数组中,只有一个数出现一次,剩下都出现三次,找出出现一次的数
因为数是出现三次的,也就是说,对于每一个二进制位,如果只出现一次的数在该二进制位为1,
那么这个二进制位在全部数字中出现次数无法被3整除。
膜3运算只有三种状态:00,01,10,因此我们可以使用两个位来表示当前位%3,对于每一位,我们让
Two,One表示当前位的状态,B表示输入数字的对应位,Two+和One+表示输出状态。
0 0 0 0 0
0 0 1 0 1
0 1 0 0 1
0 1 1 1 0
1 0 0 1 0
1 0 1 0 0
One+ = (One ^ B) & (~Two)
Two+ = (~One+) & (Two ^ B)
数组中,只有两个数出现一次,剩下都出现两次,找出出现一次的数
有了第一题的基本的思路,我们可以将数组分成两个部分,每个部分里只有一个元素出现一次,其余元素都出现两次。那么使用这种方法就可以找出这两个元素了。
不妨假设出现一个的两个元素是x,y,那么最终所有的元素异或的结果就是res = x^y。并且res!=0,那么我们可以找出res二进制表示中的某一位是1。
对于原来的数组,我们可以根据这个位置是不是1就可以将数组分成两个部分。x,y在不同的两个子数组中。而且对于其他成对出现的元素,
要么在x所在的那个数组,要么在y所在的那个数组。
例题:
给出两个整数a和b, 求他们的和, 但不能使用 + 等数学运算符。
xor 有一个别名叫做:不进位加法。
(a & b) << 1 就是进位。
所以 a+b = (a^b) + (a & b <<1)
进位不可能永远持续,所以b最终会变成0.
From 小土刀:http://wdxtub.com/interview/14520595848890.html