Python位运算
Python位运算符
按位运算符是把数字看作二进制来进行计算的
Python中的按位运算法则如下:下表中变量 a 为 60,b 为 13
|
|
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 | (a & b) 输出结果 12 ,二进制解释: 0000 1100 |
| | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1 | (a \| b) 输出结果 61 ,二进制解释: 0011 1101 |
^ | 按位异或运算符:当两对应的二进位相异时,结果为1 | (a ^ b) 输出结果 49 ,二进制解释: 0011 0001 |
~ | 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 | (~a ) 输出结果 -61 ,二进制解释: 1100 0011,在一个有符号二进制数的补码形式。 |
« | 左移动运算符:运算数的各二进位全部左移若干位,由 « 右边的数字指定了移动的位数,高位丢弃,低位补0。 | a << 2 输出结果 240 ,相当于a*2^2二进制解释: 1111 0000 |
» | 右移动运算符:把"»“左边的运算数的各二进位全部右移若干位,» 右边的数字指定了移动的位数 | a >> 2 输出结果 15 ,相当于a/2^2二进制解释: 0000 1111 |
应用实例
1 交换两个变量
|
|
2 判断奇偶数
|
|
3 找出没有重复的数
给一组整型数据,这些数据中,其中有一个数只出现了一次,其他的数都出现了两次,让你来找出一个数 。
思想:两个相同的数异或的结果是 0,一个数和 0 异或的结果是它本身,所以我们把这一组整型全部异或一下
|
|
4 m的n次方
1、直接用pow
函数
|
|
2、循环
|
|
时间复杂度为 O(n),有没有其他优化的方法呢?
3、位运算
- 把n转成二进制,如n=9,——>1001,求m的9次方,
- 即m^9 = m^1000 * m^0001,所以只需要把是1的乘数累积到结果中
- 如2^9,拆分为1000,0001(8,1)
|
|
4、递归
递归计算幂方,二分优化,2^6 = 2^3*2^3,故可以二分求幂
|
|
5 不大于N的最大2的幂指数
传统的做法就是让1不断着乘以 2,代码如下:
|
|
时间复杂度是O(logn),还有其他优化的方法吗?
采用位运算:例如 N = 19,那么转换成二进制就是 00010011。那么我们要找的数就是,把二进制中最左边的1保留,后面的 1 全部变为 0。即我们的目标数是 00010000
- 1、找到最左边的 1,然后把它右边的所有 0 变成 1
-
2、把得到的数值加 1,可以得到 00100000即 00011111 + 1 = 00100000。
-
3、把得到的 00100000 向右移动一位,即可得到 00010000,即 00100000 » 1 = 00010000。
具体的做法为:
|
|
我们假设最左边的 1 处于二进制位中的第 k 位(从左往右数),那么把 n 右移一位之后,那么得到的结果中第 k+1 位也必定为 1,然后把 n 与右移后的结果做或运算,那么得到的结果中第 k 和 第 k + 1 位必定是 1;同样的道理,再次把 n 右移两位,那么得到的结果中第 k+2和第 k+3 位必定是 1,然后再次做或运算,那么就能得到第 k, k+1, k+2, k+3 都是 1,如此往复下去….
完整代码:
|
|
6 输出集合的子集
以lst = [1,2,3,4]
为例,将子集与二进制映射。可以发现,所有子集其实就是所有元素位置为1或0
的排列。我们知道len(lst)=N
的集合子集总数为2^N
个,而list(range(2^N))
正好一一对应所有子集为1或0
的排列。
|
|
具体的代码:
|
|