使用XOR运算符交换数组在Python中不起作用

时间:2015-08-26 04:56:46

标签: python xor

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

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

我知道它应该可以工作,因为xor运算符的nilpotence(即x^x=0)并且我已经在Java和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

2 个答案:

答案 0 :(得分:4)

至于为什么它不起作用,它真的应该不重要 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 但是,如果确实想知道它为什么不起作用,那是因为这个技巧可以交换两个不同的变量,但是当你将它与相同的变量一起使用时效果不是很好,这是你在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难题)而起作用。当它是相同的变量时,第一步并没有传递信息,因为它会破坏它。

Python的'原子交换'和临时变量的使用都将完全避免这个问题。

答案 1 :(得分:1)

我正在审查这个事实,例如,你可以像下面的表达式一样表达xor:

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

所以,基本上,如果你用b替换a,哇!的xDD 你会得到它,零。