C/C++ 位运算

来源:互联网 发布:珠海金山软件宿舍 编辑:程序博客网 时间:2024/05/21 19:27

1) &

典型用法:

一是取一个位串信息的某几,如以下代码截取x的最低7位:x & 0177。

二是让某变量保留某几位,其余位置0,如以下代码让x只保留最低6位:x = x & 077


2)|

典型用法

将一个位串信息的某几位置成1。如将要获得最右4为1,其他位与变量j的其他位相同,可用逻辑或运算017|j。

若要把这结果赋给变量j,可写成: j = 017|j


3)~

典型用法:

取反运算常用来生成与系统实现无关的常。如要将变量x最低6位置成0,其余位不变,可用代码x = x & ~077实现。

以上代码与整数x用2个字节还是用4个字节实现无关。


4)^ 异或

性质

1、交换律  (a^b)^c == c^(a^b))

2、结合律(即(a^b)^c == a^(b^c))

3、对于任何数x,都有x^x=0,x^0=x

4、自反性 A^ B ^ B = A ^  0 = A

典型例子:

1)交换2个数

a = a ^ b;

b= a ^ b;   b = a ^ b ^ b = a ^ 0 = a

a= a ^ b;   a = (a ^ b) ^ a = a ^( a ^ b) = 0 ^ b = b

2)运用距离:

1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现
一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空
间,能否设计一个算法实现?

解法一、显然已经有人提出了一个比较精彩的解法,将所有数加起来,减去1+2+...+1000的和。
这个算法已经足够完美了,相信出题者的标准答案也就是这个算法,唯一的问题是,如果数列过大,则可能会导致溢出。
解法二、异或就没有这个问题,并且性能更好。
将所有的数全部异或,得到的结果与1^2^3^...^1000的结果进行异或,得到的结果就是重复数。


3)google面试题的变形:一个数组存放若干整数,一个数出现奇数次,其余数均出现偶数次,找出这个出现奇数次的数?

奇数个异或是本身,偶数个是0;0^a=a;异或有交换律。


一个整型数组里除了两个数字出现 奇数次 外,其他数字都出现 偶数次 ,请找出 只出现奇数次的 这两个数。

要求: 时间复杂度 O(n) ,空间复杂度 O(1)。


解题思路: 

我们可以想到,能不能将这两个数分开呢……


1、我们将这n个数从头到尾 异或一遍得到结果x(假设这两个数为a和b, 则a^b == x)

2、找到x的二进制表示中不为0的某一位,位置为y,然后将这n个数分成两类:y位置为1和y位置为0

3、将这两类数分别异或得到两个数a1和b1,便是我们所要求得结果


变形:

给你1到n这n个数,无序,现将其中一个数x改变成y,找出这两个数

要求: 时间复杂度 O(n) ,空间复杂度 O(1)。


原创粉丝点击