压缩时数组反向异或交换被破坏
Array Reverse XOR Swap is broken when condensed
我有一个 for 循环使用经典的 XOR 交换方法来反转数组。我尝试将代码压缩成一个表达式,但由于某种原因它中断了。谁能解释一下这是怎么回事?
首先,假设char[] s
包含单词"hello"
的字符。
这是经典算法,效果很好。
int len = s.length;
for (int i = 0; i < len / 2; i++){
s[i] ^= s[len-i-1];
s[len-i-1] ^= s[i];
s[i] ^= s[len-i-1];
}
注意到第一行的结果是第二行的输入,我就把它代入了,像这样:
int len = s.length;
for (int i = 0; i < len / 2; i++){
s[len-i-1] ^= (s[i] ^= s[len-i-1]);
s[i] ^= s[len-i-1];
}
这也很好用。但是,您可以再次看到第一行的输出用作第二行的输入。所以我又做了一次,像这样:
int len = s.length;
for (int i = 0; i < len / 2; i++){
s[i] ^= (s[len-i-1] ^= (s[i] ^= s[len-i-1]));
}
我把它加括号是为了让操作的顺序更清楚。但是当你第二次这样做时,结果很奇怪。这是上面代码直接执行后的数组:
["\u0000","\u0000","l","e","h"]
前半部分字符无效。我假设这是由于异或操作在同一件事上发生了两次,因为 (a ^ a) = 0
,但我不确定这是怎么发生的。为什么只有一半的字符被设置为 0?为什么特别是下半场?是破坏性的编译器优化吗?对此有很多疑问。如果有人可以对这里实际发生的事情进行某种细分,我们将不胜感激。非常感谢。
它与 java 计算表达式和写入内存的顺序有关。基本上,您正在执行的第二个 XOR 是在 java 开始写入内存之前读取值。因此,这种单线异或交换方法是不可能的。但是,不要害怕,因为有一种更简单的方法:
a=a^b^(b=a);
这是有效的,因为表达式 (b=a)
与 a
共鸣,但不会将 b
的值设置为 a
,直到 a
设置为 a^b^(resonance of b=a)
考虑这些操作发生的顺序有点奇怪,但希望这能引导您走正确的路。
我有一个 for 循环使用经典的 XOR 交换方法来反转数组。我尝试将代码压缩成一个表达式,但由于某种原因它中断了。谁能解释一下这是怎么回事?
首先,假设char[] s
包含单词"hello"
的字符。
这是经典算法,效果很好。
int len = s.length;
for (int i = 0; i < len / 2; i++){
s[i] ^= s[len-i-1];
s[len-i-1] ^= s[i];
s[i] ^= s[len-i-1];
}
注意到第一行的结果是第二行的输入,我就把它代入了,像这样:
int len = s.length;
for (int i = 0; i < len / 2; i++){
s[len-i-1] ^= (s[i] ^= s[len-i-1]);
s[i] ^= s[len-i-1];
}
这也很好用。但是,您可以再次看到第一行的输出用作第二行的输入。所以我又做了一次,像这样:
int len = s.length;
for (int i = 0; i < len / 2; i++){
s[i] ^= (s[len-i-1] ^= (s[i] ^= s[len-i-1]));
}
我把它加括号是为了让操作的顺序更清楚。但是当你第二次这样做时,结果很奇怪。这是上面代码直接执行后的数组:
["\u0000","\u0000","l","e","h"]
前半部分字符无效。我假设这是由于异或操作在同一件事上发生了两次,因为 (a ^ a) = 0
,但我不确定这是怎么发生的。为什么只有一半的字符被设置为 0?为什么特别是下半场?是破坏性的编译器优化吗?对此有很多疑问。如果有人可以对这里实际发生的事情进行某种细分,我们将不胜感激。非常感谢。
它与 java 计算表达式和写入内存的顺序有关。基本上,您正在执行的第二个 XOR 是在 java 开始写入内存之前读取值。因此,这种单线异或交换方法是不可能的。但是,不要害怕,因为有一种更简单的方法:
a=a^b^(b=a);
这是有效的,因为表达式 (b=a)
与 a
共鸣,但不会将 b
的值设置为 a
,直到 a
设置为 a^b^(resonance of b=a)
考虑这些操作发生的顺序有点奇怪,但希望这能引导您走正确的路。