【问题标题】:How do I compare two numbers in python(and, or, xor)?如何在 python(and, or, xor) 中比较两个数字?
【发布时间】:2021-12-05 10:42:18
【问题描述】:

我是编程新手,我正在尝试找到以下练习的 python 解决方案:

我需要比较附件图像中 3 个案例的 2 个数字的二进制形式(AND、OR、XOR)。下面是我的代码,但我不知道如何使它适用于所有 3 个案例。谢谢!

a,b = int(input("Please enter the first number: ")),int(input("Please enter the second number: ")) 
m = ""
n = ""
p = ""

print(sep="\n") 


print(bin(a),bin(b),sep="\n")
print(sep="\n") 

length = max([len(bin(a)), len(bin(b))])-2 

# AND 
for i in range(length):
    if bin(a)[-1]== "1" and bin(b)[-1]== "1":
        m+= "1"
    else:
        m+= "0"        
    a = a >> 1
    b = b >> 1 
    
    
print ("0b" + m[::-1],"| AND") 

#OR
for i in range(length):
    if bin(a)[-1]== "1" or bin(b)[-1]== "1":
        n+= "1"
    else:
        n+= "0"        
    a = a >> 1
    b = b >> 1 
   
print ("0b" + n[::-1],"| OR")  
 
#XOR
for i in range(length):
    if bin(a)[-1] != bin(b)[-1] :
        p+= "1"
    else:
        p+= "0"      
    a = a >> 1
    b = b >> 1 
print ("0b" + p[::-1],"| XOR")

【问题讨论】:

  • wiki.python.org/moin/BitwiseOperators(只是因为那里还有其他文章,python 文档非常好,值得收藏)
  • @2e0byo 我也认为按位运算符是需要的,但似乎他们正试图以艰难的方式做事。老实说,我再也看不到代码有问题了,除了操作的执行顺序可能与示例不同。我当然无法确定哪个案例失败了。
  • @MarkRansom 公平;我将手动添加到我的答案中。
  • @2e0byo 不要把代码放在银盘上,这显然是一种学习练习,你会对他们造成伤害。
  • @MarkRansom 哦,别担心,我不会(也不会)写出此类问题的答案 :)

标签: python binary


【解决方案1】:

问题在于第一个循环修改了您的输入变量ab 并将它们保留为零。这意味着第二个和第三个循环没有任何用处。

解决此问题的最简单方法是将每个循环放在一个单独的函数中,该函数无法修改传入的值,因此它们会自动恢复。

【讨论】:

  • 你好,谢谢你,这是我想弄清楚的!
  • @sada995 如果您将实际结果放在问题中,我本可以更快地弄清楚。您甚至从未提及哪些案例失败了!
【解决方案2】:

我写了一个很长的答案,因为我希望有人在 第一次学习 python 时有。请注意,我非常刻意地遍历所有步骤,并且我没有提供所有内容的最终代码。对不起,如果它太慢了:我试图清楚,而不是光顾。请注意,您的代码的“问题”仅仅是使用位移来修改 a 和 b。

在这段代码中有很多“有趣”的做事方式,可能值得考虑以下“标准”解决方案:

打印空行

print(sep="\n")

这根本不起作用,因为sep 仅在有多个条目时应用。比较一下:

print("hello", "world", sep="\n")

你能看到sep 做了什么吗?这行代码执行您认为的原因是end 的默认值 \n。打印空行可以使用print(end="\n"),相当于print(),所以首选后一种形式。

按位比较

在位级别比较两个数字的最简单方法是使用按位运算:

a = 0b11110000
b = 0b10101010
a & b # and

其他位运算符见:

https://wiki.python.org/moin/BitwiseOperators

手动按位

手动按位问题可以被认为是“按数字迭代数字并在数字上做一些事情”。对于第一个问题,您已经有了一个很好的解决方案:使用 bin() 获取一个字符串并对其进行迭代。但是您有一些范式在起作用,包括使用<< 进行移位,正如@MarkRansom 所指出的那样,它正在修改您的整数。采用单一迭代范式会更“标准”。天真:

a = bin(0b11110000)
b = bin(0b10101010)

for i in range(len(a):
   a_digit = int(a[i])
   b_digit = int(b[i])
   # comparison here

但更惯用:

for a_digit, b_digit in zip(a, b):
    comparison(int(a_digit), int(b_digit))

以 'and' 为例,因为它是最简单的(我把其他比较留给你),测试显然是 a_digit == 1 and b_digit == 1。所以我们会写:

res = []
for a_digit, b_digit in zip(a,b):
    res.append(int(a_digit) == 1 and int(b_digit == 1))
# res = [True, True, True, True, False, False, False, False]

但请记住 1 在 python 中是真实的,最好是:

res.append(int(a_digit) and int(b_digit))

如果我们想要 1 和 0:

res.append(1 if int(a_digit) and int(b_digit) else 0)

此时我们已准备好将其全部包装成列表推导式:

res = [1 if int(a_digit) and int(b_digit) else 0 for a_digit, b_digit in zip(a,b)]

这个范式真的很值得学习。 listcomp 可能是“手动”解决每个问题的最正常方法,并且我在此处遵循的步骤可以用于其他情况(或 xor、nand 等)。

附录:长度不等

正如 cmets 中所指出的,如果 ab 的长度不相等会怎样?我没有解决这个问题,也没有跳过b 表示。 (请注意,bin() 会截断例如 0011)就个人而言,如果手动执行此操作,我会让用户输入 strings 并处理它们。对于不相等的长度,您有两种选择:用零填充,或在反向输入上使用 zip_longest

a = "100100"
b = "1011100"
l = max(len(a), len(b))
for a_digit, b_digit in zip(a.rjust(l, "0"), b.rjust(l, "0")):
    ...

这里我们将右对齐设置为最长的长度(因为 LSB 在 右侧 手边)。或者:

from itertools import zip_longest
for a_digit, b_digit in zip_longest(reversed(a), reversed(b), fillvalue="0"):
    ...

请注意,在这种情况下,我们故意从 LSB 到 MSB,因此数字的顺序是倒序的。 zip_longest 将为我们填写,默认情况下使用None,但这里使用"0"。请注意,zip 会截断最短参数的长度。

当然,如果您的数字表示为大端字符串,而不是您从 python 的 bin() 获得的小端字符串,则不需要反转,您可能需要 ljust 来获得其他解决方案。

【讨论】:

  • 您好,谢谢您,现在一切都清楚了。祝您有美好的一天!:)
  • @sada995 请注意,我错过了演员表(现在添加),因为我们正在迭代一个字符串。我还在早上的大脑中:)但这无论如何都是骨架代码
  • zip 技巧只有在两个字符串大小相同时才能正常工作。您可以通过使用a=a.rjust(length,'0')b 来确保这一点。不过,你提出了很多好的观点。
  • @MarkRansom 很好,我会补充的
【解决方案3】:
def decimalToBinary(n):
    return bin(n).replace("0b", "")

## Uncomment the below two lines of code, if you are inputting the numbers in decimal format
# bin_a = str(decimalToBinary(int(input("Enter first number: "))))
# bin_b = str(decimalToBinary(int(input("Enter second number: "))))

## Uncomment the below two lines of code, if you are inputting the numbers in binary format
# bin_a = str(int(input("Enter first number: ")))
# bin_b = str(int(input("Enter second number: ")))

len_bin_a = len(bin_a)
len_bin_b = len(bin_b)

if len_bin_a > len_bin_b:
    bin_b = "0" * (len_bin_a - len_bin_b) + bin_b

elif len_bin_a < len_bin_b:
    bin_a = "0" * (len_bin_b - len_bin_a) + bin_a

or_result = "".join([str(int(bin_a[i]) | int(bin_b[i])) for i in range(len(bin_a))])
and_result = "".join([str(int(bin_a[i]) & int(bin_b[i])) for i in range(len(bin_a))])
xor_result = "".join([str(int(bin_a[i]) ^ int(bin_b[i])) for i in range(len(bin_a))])

print(or_result + "\tOR")
print(and_result + "\tAND")
print(xor_result + "\tXOR")

如果你想深入了解 Python 中的位运算符,我会在下面留下一个链接

https://www.geeksforgeeks.org/python-bitwise-operators/

希望代码能达到目的

问候

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 2015-05-09
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多