将数据清零时奇怪的异或交换行为
谢谢道格。修复方法如下:
void swap(int& a, int& b) {
if (&a == &b) // added this check to ensure the same address is not passed in
return;
a ^= b;
b ^= a;
a ^= b;
}
我在 C++ 中实现快速排序是为了好玩,并且我使用整数作为虚拟数据。我一直在使用 XOR 交换算法来交换两个值,但我注意到我的排序搞砸了。我改变了交换算法并且它起作用了。我添加了一些调试语句,发现 XOR 交换做了一些奇怪的事情。
我在交换它之前和之后打印了数据,这就是它打印的内容:
...
swapping -5, -3
swapped -3, -5
swapping -5, -5
swapped 0, 0 <---- What?
swapping -2, -4
swapped -4, -2
...
这是我的代码:
// this might not be that great or even work as intended but it doesn't really matter for this problem
int av3index(int a[], int indx1, int indx2, int indx3) {
if (a[indx3] <= max(a[indx1], a[indx2]) && a[indx3] >= min(a[indx1], a[indx2]))
return indx3;
if (a[indx2] <= max(a[indx1], a[indx3]) && a[indx2] >= min(a[indx1], a[indx3]))
return indx2;
if (a[indx1] <= max(a[indx2], a[indx3]) && a[indx1] >= min(a[indx2], a[indx3]))
return indx1;
}
void swap(int& a, int& b) {
/*
This works
int tmp = b;
b = a;
a = tmp;*/
cout << "swapping " << a << ", " << b << endl;
a ^= b;
b ^= a;
a ^= b;
cout << "swapped " << a << ", " << b << endl << endl;
}
void zqsort(int a[], int len) {
if (len <= 1)
return;
int pivot = av3index(a, 0, len / 2, len - 1);
swap(a[pivot], a[0]);
int i = 1, j = len - 1;
while (i <= j) {
if (a[i] > a[0]) {
while (i <= j && a[j] > a[0])
--j;
if (i <= j)
swap(a[i], a[j]);
}
++i;
}
swap(a[0], a[j]);
zqsort(a, len / 2);
zqsort(a + len / 2, len - len / 2);
}
int main() {
int values[] = {5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5};
int len = sizeof(values) / sizeof(int);
int* arr = new int[len];
for (int i = 0; i < len; ++i)
arr[i] = values[i];
zqsort(arr, len);
cout << "sorted array:" << endl;
for (int i = 0; i < len; ++i)
cout << arr[i] << endl;
cin.get();
}
我没有使用快速排序代码的任何引用,因此它可能是错误的,但我认为这与问题。
Thanks Doug. Here's the fix:
void swap(int& a, int& b) {
if (&a == &b) // added this check to ensure the same address is not passed in
return;
a ^= b;
b ^= a;
a ^= b;
}
I am implementing quicksort for fun in C++, and I am using integers for dummy data. I had been using the XOR swapping algorithm to swap two values in place, but I noticed my sort was screwing up. I changed my swapping algorithm and it worked. I added some debugging statements, and found that the XOR swap was doing something weird.
I printed the data before and after I swapped it, and this is what it printed:
...
swapping -5, -3
swapped -3, -5
swapping -5, -5
swapped 0, 0 <---- What?
swapping -2, -4
swapped -4, -2
...
Here is my code:
// this might not be that great or even work as intended but it doesn't really matter for this problem
int av3index(int a[], int indx1, int indx2, int indx3) {
if (a[indx3] <= max(a[indx1], a[indx2]) && a[indx3] >= min(a[indx1], a[indx2]))
return indx3;
if (a[indx2] <= max(a[indx1], a[indx3]) && a[indx2] >= min(a[indx1], a[indx3]))
return indx2;
if (a[indx1] <= max(a[indx2], a[indx3]) && a[indx1] >= min(a[indx2], a[indx3]))
return indx1;
}
void swap(int& a, int& b) {
/*
This works
int tmp = b;
b = a;
a = tmp;*/
cout << "swapping " << a << ", " << b << endl;
a ^= b;
b ^= a;
a ^= b;
cout << "swapped " << a << ", " << b << endl << endl;
}
void zqsort(int a[], int len) {
if (len <= 1)
return;
int pivot = av3index(a, 0, len / 2, len - 1);
swap(a[pivot], a[0]);
int i = 1, j = len - 1;
while (i <= j) {
if (a[i] > a[0]) {
while (i <= j && a[j] > a[0])
--j;
if (i <= j)
swap(a[i], a[j]);
}
++i;
}
swap(a[0], a[j]);
zqsort(a, len / 2);
zqsort(a + len / 2, len - len / 2);
}
int main() {
int values[] = {5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5};
int len = sizeof(values) / sizeof(int);
int* arr = new int[len];
for (int i = 0; i < len; ++i)
arr[i] = values[i];
zqsort(arr, len);
cout << "sorted array:" << endl;
for (int i = 0; i < len; ++i)
cout << arr[i] << endl;
cin.get();
}
I didn't use any references for the quicksort code so it might be wrong, but I don't think that's germane to the problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的交换
a
和b
位于同一位置。 XOR hack仅在它们位于不同位置时才有效。我认为用C语言;这是一张表:
Your swap
a
andb
are the same location. The XOR hack only works when they are different locations.I think in C; here's a table:
除了现有的答案之外,我只是补充一点,如果您要在交换之前进行测试,那么您不妨将其更改
为
:这将处理
&a == &b 的情况
以及a == b
的情况,这可能会节省一些不必要的交换。In addition to the existing answers, I'll just add that if you're going to do a test before swapping then you might as well change:
to:
This will handle the case where
&a == &b
and also the case wherea == b
, which may save some unnecessary swapping.任何与自身异或的值都是零。
Anything xor'd with itself is zero.