【问题标题】:Swapping array with the XOR operator doesn’t work in Python使用 XOR 运算符交换数组在 Python 中不起作用
【发布时间】:2015-08-26 04:56:45
【问题描述】:

我试图在 Python 中编写 Quicksort(请参阅问题末尾的完整代码)和在分区函数中我应该交换数组的两个元素(称为 x)。我正在使用以下代码基于 xor 运算符进行交换:

x[i]^=x[j]
x[j]^=x[i]
x[i]^=x[j]

我知道它应该可以工作,因为 xor 运算符(即x^x=0)的幂等性,而且我已经在 J​​ava 和 C 中做了一百万次,没有任何问题。我的问题是:为什么它在 Python 中不起作用? x[i] == x[j](可能是i = j?)时似乎不起作用。

x = [2,4,3,5,2,5,46,2,5,6,2,5]
print x
def part(a,b):
  global x
  i = a
  for j in range(a,b):
    if x[j]<=x[b]:
      x[i]^=x[j]#t = x[i]
      x[j]^=x[i]#x[i] = x[j]
      x[i]^=x[j]#x[j]=t
      i = i+1
  r = x[i]
  x[i]=x[b]
  x[b]=r
  return i
def quick(y,z):
  if z-y<=0:
    return
  p = part(y,z)
  quick(y,p-1)
  quick(p+1,z)
quick(0,len(x)-1)
print x

【问题讨论】:

  • 那么你的问题是什么?你得到错误的输出吗?如果是这样,您应该将其包含在问题中。
  • 这 3 行确实有效,所以问题出在其他地方。但正如 paxdiablo 在他的回答中所说,你不应该那样交换。
  • @AnandSKumar 感谢您的提问。我的问题是为什么它不起作用。如果我使用异或交换,我得到 [0, 0, 0, 0, 0, 0, 0, 2, 5, 5, 6, 46],如果我使用注释代码,我得到 [2, 2, 2, 2 , 3, 4, 5, 5, 5, 5, 6, 46]
  • @Cyphase 感谢您的回复,问题就在这里。我使用注释交换,它有效。
  • @user16117,这很奇怪;我没有运行您的确切代码,但 d=[1,2]; d[0]^=d[1];d[1]^=d[0];d[0]^=d[1] 对我有用; d 将是 [2,1]

标签: python xor


【解决方案1】:

至于为什么它不起作用,这真的不重要1,因为你shouldn't be using一开始就是这样的代码,尤其是当Python为您提供完美的“原子交换”功能:

x[i], x[j] = x[j], x[i]

我一直认为,所有程序最初都应该首先针对可读性进行优化,并且只有在有明确的需求和明显的好处时才进行性能或存储改进(我从未见过除某些之外的 XOR 技巧)非常小的数据环境,例如一些嵌入式系统)。

即使在提供这种漂亮特性的语言中,使用临时变量也更具可读性并且可能更快:

tmp = x[i]
x[i] = x[j]
x[j] = tmp

1 但是,如果您真的想知道它为什么不起作用,那是因为该技巧可以交换两个 不同 变量,但当您将它与 same 变量一起使用时效果不佳,当您尝试将 x[i]x[j] 交换时,当 i 等于 j 时,您将执行此操作.

它在功能上等同于以下内容,添加了 print 语句,因此您可以看到整个事情在哪里分崩离析:

>>> a = 42
>>> a ^= a ; print(a)
0
>>> a ^= a ; print(a)
0
>>> a ^= a ; print(a)
0

将其与两个 不同 变量进行对比,效果还不错:

>>> a = 314159; b = 271828; print(a,b)
314159 271828

>>> a ^= b; print(a,b)
61179 271828

>>> b ^= a; print(a,b)
61179 314159

>>> a ^= b; print(a,b)
271828 314159

问题在于,这个技巧通过在两个变量之间逐渐传递信息来起作用(类似于fox/goose/beans 谜题)。当它是 same 变量时,第一步不会传递信息,而是会破坏它。

Python 的“原子交换”和使用临时变量都可以完全避免这个问题。

【讨论】:

  • 是的,您现在的最后一次更新,这确实是问题所在,那么,我们为什么要解释这种行为?很奇怪,不是吗?
  • 感谢您回答 paxdiablo。为什么不重要?我不是本地 python 编码器,我不习惯这些表达方式。我知道它是这样工作的,我很感激这些知识,但对我来说,重要的是为什么/如何工作以及为什么/如何不工作。
  • @user16117 如果您将xor 用于具有相同数字的任何数字,它会给您一个零。那么如何从零复制相同的数字呢?
  • @niyasc Ah 0k,我现在明白了。我使用的是完全相同的变量。谢谢:)
  • @niyasc,问题不在于数字相同,而在于x[i]x[j] 指的是同一个变量。 x[i] 可以等于x[j],只要i 不等于j
【解决方案2】:

我正在审查这个事实,例如,您可以将 xor 表示为以下表达式:

a xor b = (a or b) - (a & b)

所以,基本上,如果您将 a 替换为 b,哇! xDD 你会明白的,零。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 2015-05-01
    • 2013-08-13
    • 2012-05-19
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多