文章目录
一、位运算符
符号 | 描述 | 作用 |
---|---|---|
& | 与运算 | 两个都为1,结果为1 |
| | 或运算 | 只要有一个为1,结果为1 |
^ | 异或 | 同为0,异为1 |
~ | 取反 | 0变为1,1变为0 |
<< | 左移 | 左移,末位补0 |
>> | 右移 | 右移,高位补0 |
二、例题
1、二进制中1的个数
1.1 题目
请实现一个函数,输入一个整数n,输出该数二进制表示中1的个数。
例:9的二进制表示为1001,有2位是1
1.2 分析
只要将整数n与n-1进行与运算&,就可以删掉末位的1,例如:n=14,n的二进制为1110,n-1的二进制就是1101,进行与运算(都为1,结果为1),得到1100,此时末位的1被删掉。因此,我们只要不断的将n与n-1进行与运算并更新n,直到n=0时退出循环,此时循环的次数就是该数二进制表示中1的个数。
1.3 python代码
n = int(input())
res = 0
while n != 0:
n = n & (n-1)
res += 1 # 记录循环次数
print(res)
2、是不是2的整数次方
2.1 题目
用一条语句判断一个整数是不是2的整数次方。如果是就输出"yes",如果不是就输出"no"。
例:8是2的整数次方,输出"yes";9不是2的整数次方,输出"no"。
2.2 分析
这题比上一题更加简单,也是用与运算来解决。首先,我们来理解题目,如果一个数是2的整数次方(例:2^0 ,2的1次方,2的2次方等等),则说明二进制表达式中只有最高位为1,其他位都为0,因此只需要将n和n-1进行与运算,只要与运算结果为0,则说明除了最高位为1之外,其他位都是0,反之,则说明该数的二进制表达中不只一个1。
2.3 python代码
n=int(input())
if n & (n-1)==0:
print("yes")
else:
print("no")
3、小小蓝的异或消除
3.1 题目描述
小小蓝是一名天才程序员,他研究了一种特殊的数组操作,他称之为“异或消除”。
对一个整数数组arr执行一次“异或消除”操作,可以拆解成以下四个步骤:
- 找到数组中的最大值a和次大值b,若有多个相同的最大值或次大值,取最左边的那个。
- 将a和b两个元素同时从数组中移除。
- 计算a和b的异或值c = a ⊕ b。
- 将c放入数组的最左边。
小小蓝想知道,对于给定的数组arr,经过不断的“异或消除”操作后,数组中最后留下的元素。他请你编写一个程序来帮助他解决这个问题。
输入格式
输入包含两行。
输入的第一行,包含一个整数n(1≤n≤10^5),表示数组arr的长度。
输入的第二行,包含n个整数,表示数组arr中的元素。
输出格式
输出仅一行,包含一个整数,表示数组中最后留下的元素。
样例输入
5
3 5 7 5 3
样例输出
7
说明
- 第一次异或消除操作,取出7和5,异或得2,数组变为[2,3,5,3]。
- 第二次异或消除操作,取出5和3,异或得6,数组变为[6,2,3]。
- 第三次异或消除操作,取出6和3,异或得5,数组变为[5,2]。
- 第四次异或消除操作,取出5和2,异或得7,数组变为[7]。
3.2 python代码
最开始的时候,我按照题意,直接写的代码,但是发现运行速度较慢,因此后面换了一个思路重新写了一个代码,运行速度大幅提升。
下面是最先写的代码:
# 原代码
import time
start = time.perf_counter() # 存储初始时间
n=int(input())
arr=list(map(int,input().split()))
for i in range(n-1):
m1=max(arr)
arr.pop(arr.index(m1))
m2=max(arr)
arr.pop(arr.index(m2))
c=m1 ^ m2
arr.append(c)
print(arr[0])
end=time.perf_counter() # 存储结束时间
print(str(end-start)) # 计算运行时间
输出结果:
12
2 5 27 4 3 48 12 37 8 4 5 82
89
30.7753576
下面这个是后面改进后的代码:
import time
start = time.perf_counter()
n=int(input())
arr=list(map(int,input().split()))
res=0
for i in range(n):
res^=max(arr)
arr.pop(arr.index(max(arr)))
print(res)
end=time.perf_counter()
print(str(end-start))
输出结果:
12
2 5 27 4 3 48 12 37 8 4 5 82
89
1.3495462999999999 # 可以看到对比上面,速度有明显的提升