Task 01 - 利用位运算实现整数集合 Python基础入门:从变量到异常处理(第一二天)

Task 01 - 利用位运算实现整数集合

Python基础入门:从变量到异常处理(第一二天)

在这里插入图片描述

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 的补码为 1011

x先得出原码,然后符号位不变,其余位取反加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基础入门:从变量到异常处理(第三天)

望批评指正

如果认为对你学习有帮助

欢迎收藏❤帮我点个赞👍谢谢你哦❤

未经同意不准转载^ . ^

部分材料来源于 阿里云天池Python训练营
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值