Task 01 - 利用位运算实现整数集合
1.3 运算符 - 位运算符
补充
0b100 中0b表示什么?
当没有前导0时会出现问题。Python的变量命名约定是,它必须以字母字符开头。如果前导0,则解释器可以判断它是文字还是变量。请勿将二进制文字与变量混淆,0b指二进制,0x 指十六进制
其中0b开头表示正数, -0b表示负数
0b100即 0100
-0b101 即 1101两个方法求解负整数的补码
将其对应正数(无符号数)二进制表示所有位取反(包括符号位,0变1,1变0)后加1
如 -5 的对应正数(无符号数) 即 5 的二进制表示为 0101,所有位取反为 1010, 加1为 1011,故 -5 的补码为 1011x先得出原码,然后符号位不变,其余位取反加1
先得出 -5 的原码,即 1101, 再求其补码,即符号位不变,其余位取反加1,得 1011记住,对于正整数, 原码 = 反码 = 补码
解析
print(bin(~4),~4) # -0b101 -5
python里,使用原码进行展示,补码参与运算
4 的原码是 0b100 , 补码也是 0b100
print(bin(4)) # 0b100
补码进行运算操作
~4 -> ~0b100 -> ~0100 -> 1011 -> -0b011
运算完毕结果为补码-0b011 需要将其转换为原码进行展示
-0b011 -> 1011 符号位不变其它位取反加1
即 1100 + 0001 = 1101 -> -0b101
print(bin(~4)) # -0b101
print(bin(~4),~4) # -0b101 -5
再举例 负数例子
print(bin(-6)) # -0b110
print(bin(~-6),~-6) # 0b101 5
先求-6的补码,即 +6(0110)取反后再+1:
(1001)+(0001)=(1010)
计算机中-6是用(1010)来存储的,(1010) 按位取反得到(0101)即5
-6
无符号数 0110(无符号数)
原码 1110 即: -0b110
补码 1010 即: -0b010
按位取反 0101 即: 0b101
2.9 利用位运算实现整数集合
一个数的二进制表示可以看作是一个集合(0 表示不在集合中,1 表示在集合中)。
比如集合 {1, 3, 4, 8},可以表示成 01 00 01 10 10 而对应的位运算也就可以看作是对集合进行的操作。
元素与集合的操作:
集合之间的操作:a | (1 << i) -> 把i插入到集合中
a & ~(1<< i)-> 把i从集合中删除
a & (1<< i) -> 判断i是否属于该集合 (零不属于, 非零属于)
解析
所以,这个集合与二进制的对应关系的操作具体是怎样的呢?
我自己捣鼓了一下(只针对正整数的二进制哟,刚好对应集合里的正整数)
def set_to_num(x):
list_zeros = [0 for x in range(0,max(x)+1)]
location_set = [max(x)-i for i in x]
for j in location_set:
list_zeros[j] = 1
list_out = [str(i) for i in list_zeros]
to_num = str(''.join(list_out))
str_l = '0b'+to_num
out_num = int(str_l, 2)
return out_num
def num_to_set(x):
name = [int(v) for v in(bin(x))[2:]]
location = 0
find = 1
location_set = set()
for i in range(name.count(find)):
location += name[location:].index(find)
location_set.add(location)
location += 1
location_set = [len(name)-1-i for i in location_set]
location_set = sorted(location_set)
print(type(location_set))
print(location_set)
a = 0b100011010 # [1, 3, 4, 8]
b = 0b100010010 # [1, 4, 8]
list_a = [1, 3, 4, 8]
num_to_set(a) # [1, 3, 4, 8]
result = set_to_num(list_a)
i = 5
# 集合之间的操作:
# a | (1 << i) -> 把i插入到集合中
insert_i = a | (1 << i)
num_to_set(insert_i)
# [1, 3, 4, 5, 8]
print('After insert_i, insert_i is :',bin(insert_i))
# After insert_i, insert_i is : 0b100111010
# a & ~(1<< i)-> 把i从集合中删除
i = 4
remove_i = a & ~(1<< i)
num_to_set(remove_i)
# [1, 3, 8]
print('After remove_i, remove_i is :',bin(remove_i))
# After remove_i, remove_i is : 0b100001010
# a & (1<< i) -> 判断i是否属于该集合 (零不属于, 非零属于)
i = 6
assert_i = a & (1<< i)
num_to_set(assert_i)
# []
print('After assert_i, assert_i is :',bin(assert_i))
# After assert_i, assert_i is : 0b0
# a 交 b
c = a & b
num_to_set(c)
# [1, 4, 8]
print('After a & b, a & b is :',bin(c))
# After a & b, a & b is : 0b100010010
Task 02 - 部分学习内容解析与补充 Python基础练习:数据结构大汇总(第一天)
Task 01 - 部分学习内容解析与补充 Python基础入门:从变量到异常处理(第三天)
望批评指正
如果认为对你学习有帮助
欢迎收藏❤帮我点个赞👍谢谢你哦❤
未经同意不准转载^ . ^