位运算

方法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。

位运算_第1张图片


难例题:

如果要将整数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.



位运算_第2张图片


From 小土刀:http://wdxtub.com/interview/14520595848890.html


位运算_第3张图片
位运算_第4张图片
位运算_第5张图片
位运算_第6张图片
位运算_第7张图片
位运算_第8张图片
位运算_第9张图片

你可能感兴趣的:(位运算)