Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的XOR交换算法?_Python_Algorithm_Tuples - Fatal编程技术网

python中的XOR交换算法?

python中的XOR交换算法?,python,algorithm,tuples,Python,Algorithm,Tuples,我尝试用python实现 x,y= 10,20 x,y,x = x^y,x^y,x^y print('%s , %s'%(x,y)) 输出: 30 , 30 我对python并不陌生,但我无法解释这个输出。它应该是20,10 引擎盖下发生了什么?首先,创建一个元组,由x^y、x^y和x^y组成。然后将元组解压为x、y和x,从而使两者都绑定到x^y的结果 省去你的头痛,用蟒蛇式的方法来做: x, y = y, x 您可以使用以下方法轻松完成此交换: x, y = 10, 20 x, y

我尝试用python实现

x,y= 10,20

x,y,x = x^y,x^y,x^y

print('%s , %s'%(x,y))
输出:

30 , 30
我对python并不陌生,但我无法解释这个输出。它应该是
20,10


引擎盖下发生了什么?

首先,创建一个元组,由
x^y
x^y
x^y
组成。然后将元组解压为
x
y
x
,从而使两者都绑定到
x^y
的结果

省去你的头痛,用蟒蛇式的方法来做:

x, y = y, x

您可以使用以下方法轻松完成此交换:

x, y = 10, 20 x, y = y, x print((x,y)) x、 y=10,20 x、 y=y,x 打印((x,y))
至于你看到的行为,我很确定这是因为整个RHS都被计算,然后同时分配给LHS,在这种情况下,
x^y
总是30。

只有当你有两个指向可变对象的指针时,XOR交换算法才有意义。a和b是对不可变整数的两个引用

编辑(根据请求从注释移动,并展开):

Python整数是不可变的。因此,每次使用XOR“修改”一个存储时,都会分配新的存储(或重新使用,例如用于实习)。这与(例如C)有根本不同,在C中,交换更改值而不分配新内存。换句话说,XOR swap不会在C99意义上(执行环境中的数据存储区域,其内容可以表示值)或Python意义上创建新对象。如前所述,真正的异或交换可以“交换变量a和b的值,而无需为临时变量使用额外的空间。”

或者根据经验:

>>> x = 3
>>> y = 5
>>> print "x: ", x, ", id(x): ", id(x), "y: ", y, ", id(y): ", id(y)
x:  3 , id(x):  137452872 y:  5 , id(y):  137452848
>>> x ^= y
>>> print "x: ", x, ", id(x): ", id(x), "y: ", y, ", id(y): ", id(y)
x:  6 , id(x):  137452836 y:  5 , id(y):  137452848
>>> y ^= x
>>> print "x: ", x, ", id(x): ", id(x), "y: ", y, ", id(y): ", id(y)
x:  6 , id(x):  137452836 y:  3 , id(y):  137452872
>>> x ^= y
>>> print "x: ", x, ", id(x): ", id(x), "y: ", y, ", id(y): ", id(y)
x:  5 , id(x):  137452848 y:  3 , id(y):  137452872
在本例中,我们看到解释器(2.6.4)似乎是,因此x以最初的内存地址y结束。但主要的一点是,交换至少需要一个分配(137452836),并且x和y在整个过程中不保留相同的内存地址

在C中:

给出:

x: 3, &x: 0xbfd433ec, y: 5, &y: 0xbfd433e8
x: 6, &x: 0xbfd433ec, y: 5, &y: 0xbfd433e8
x: 6, &x: 0xbfd433ec, y: 3, &y: 0xbfd433e8
x: 5, &x: 0xbfd433ec, y: 3, &y: 0xbfd433e8

这是一个真正的异或交换,因此x和y始终保持相同的内存位置,并且没有临时性的存储。

虽然它绝对是最好的,正如其他答案所说,只需
x,y=y,x
,如果你对创建和解包元组过敏,你可以通过连续的x-oring来实现。。。它必须是连续的,而不是像你所做的那样同时发生

>>> x = 1234
>>> y = 3421
>>> x ^= y
>>> y ^= x
>>> x ^= y
>>> print x
3421
>>> print y
1234

异或交换技巧的关键是三个连续的异或,即一个在另一个之后——在这个片段中,三个独立的
^=
语句。当然,它没有实际意义,但是,如果您真的对它感兴趣,它确实可以工作,就像其他任何地方一样,在Python中;-)

您需要逐行转录“算法”

>>> x, y = 10, 20
>>> x = x ^ y; print x, y
30 20
>>> y = x ^ y; print x, y
30 10
>>> x = x ^ y; print x, y
20 10
>>>
您需要阅读Wikipedia文章的其余部分,其中解释了正确的实现会阻止并行操作,并且整个想法几乎毫无用处(至少在现代计算机体系结构上)。

您可以将“元组交换”和“:x,y=x^x^y,x^y^y

Python:

x, y = 10, 20
print('Before swapping: x = %s, y = %s '%(x,y))

x, y = x ^ x ^ y, x ^ y ^ y
print('After swapping: x = %s, y = %s '%(x,y))

输出:

Before swapping: x =  10 , y =  20
After swapping: x =  20 , y =  10

@Matthew,正如我的回答所示,它对不可变int的引用和对可变对象的指针的引用一样有意义(也就是说,意义不大)。这是暂时的连续性与同时的评估,这才是问题的关键!我认为我们混淆了交换过程实现的目的和XOR算法本身。当您不想使用额外的存储时,可以选择XOR实现,但这样做绝对需要可变数据。因此,如果使用XOR创建新值,即使它可以正常工作-如您的答案中所示,Alex-没有什么意义,因为您可以将新值用作临时值。数学是可行的,但节省空间交换的基本目标没有得到满足。当您这样做时,Python不会修改int的位置,因此,即使分三步进行,也无法避免使用您预期的额外临时存储。您的意思是说,在python中,如果不使用任何额外存储,xor排序是不可能的吗?@Matthew Flaschen:请将您的答案作为答案发布,而不是评论。请删除评论并插入一个答案,这样我们就可以正确地向上投票了。它不应该是XOR交换而不是排序吗?@Matthew:XOR交换不知道对象是什么。Alex的代码模拟寄存器中发生的事情。使用
reg=[10,20]
并对
reg[0]
reg[1]
进行操作,如果这能让您感觉更好:-)@Matthew,在Python中,每个整数操作都可能“创建一个新对象”,也可能不会这样做:这完全取决于实现,因为它严格来说是一个性能问题(对语义没有任何影响!),应用程序代码无法控制它。例如,可能会缓存小整数(因此实际上不会为整数创建新对象<某个阈值,完全取决于Python实现),如果实现可以证明对现有对象的最后一次引用被删除,则可以重用现有对象的内存,等等。您对创建的保证是错误的(更多…)@Matthew,详细回应您的海洋律师:“不使用额外的空间作为临时变量”——这里没有使用额外的变量(可能有额外的对象——它们不是变量而是不可变的——但绝对没有变量,所以我们可以!)。并且:如果一个对象是“执行环境中的数据存储区域”,那么Python对象在最后一个引用删除后就不再是对象,因为这意味着它不在执行环境中——它是环境下的底层实现可以随意使用(或不使用)的死位。@Matthew,标识符的可用性与编译器能够使对象可访问的能力无关:例如,一个实现可以决定<代码> > x x /COD>在任何范围内都是可见的,并且返回一个指针,允许访问所述对象(“保留给实现的任何使用”,在C++ STD(2003)中,每一个7.1.3,每C STD(1999)7.1.3个)。,这样就可以使用了)那么
x, y = 10, 20

print('Before swapping: x = %s, y = %s '%(x,y))
print('After swapping: x = %s, y = %s '%(x ^ x ^ y, x ^ y ^ y))
Before swapping: x =  10 , y =  20
After swapping: x =  20 , y =  10