gpt4 book ai didi

java - XOR 交换在所有情况下都等同于传统交换吗?

转载 作者:太空宇宙 更新时间:2023-11-04 06:36:17 25 4
gpt4 key购买 nike

下面是执行“就地”字符串反转的方法,即黑猫变成猫黑。 在第二个交换部分中,如果使用传统交换(已注释掉),则所有测试都会通过,但如果使用异或交换,则只有一个测试通过。

难道不能简单地“交换”吗

        for (int i = count; i <= (end + count) / 2; i++) {
char temp = arr[i];
arr[i] = arr[end - (i - count)];
arr[end - (i - count)] = temp;
}

        for (int i = count; i <= (end + count) / 2; i++) {
arr[i] ^= arr[end - (i - count)];
arr[end - (i - count)] ^= arr[i];
arr[i] ^= arr[end - (i - count)];
}

方法

public class ReverseString {

public static char[] revString(String input) {

char[] arr = input.toCharArray();
int length = arr.length;

for (int i = 0; i < (length / 2); i++) {
arr[i] ^= arr[length - i - 1];
arr[length - i - 1] ^= arr[i];
arr[i] ^= arr[length - i - 1];
}

int end;
int charCount;
int count = 0;
while (count < length) {

if (arr[count] != ' ') {

charCount = 0;
while (count + charCount < length && arr[count + charCount] != ' ') {
charCount++;
}

end = count + charCount - 1;

// for (int i = count; i <= (end + count) / 2; i++) {
// char temp = arr[i];
// arr[i] = arr[end - (i - count)];
// arr[end - (i - count)] = temp;
// }

for (int i = count; i <= (end + count) / 2; i++) {
arr[i] ^= arr[end - (i - count)];
arr[end - (i - count)] ^= arr[i];
arr[i] ^= arr[end - (i - count)];
}

count += charCount;

} else {
count++;
}
}
return arr;
}
}

测试

@RunWith(JUnitParamsRunner.class)
public class ReverseStringTest {

@Test
@Parameters(method = "getStrings")
public void testRevString(String testValue, char[] expectedValue) {
assertThat(ReverseString.revString(testValue), equalTo(expectedValue));
}

private static final Object[] getStrings() {
return new Object[] {
new Object[] {"Black Cat", "Cat Black".toCharArray()},
new Object[] {"left to", "to left".toCharArray()}
};
}
}

失败的输出

java.lang.AssertionError: 
Expected: ["C", "a", "t", " ", "B", "l", "a", "c", "k"]
but: was ["C", "

最佳答案

与自身交换值时,异或交换失败。这是您的代码:

arr[i] ^= arr[end - (i - count)];
arr[end - (i - count)] ^= arr[i];
arr[i] ^= arr[end - (i - count)];

假设i == end - (i - count)。然后:

arr[i] ^= arr[end - (i - count)];

arr[i]设置为零(因为与自身进行异或的任何内容都是零)。

接下来的两行不执行任何操作,因为与零进行异或运算无效,将 arr[i] 保留为零,从而损坏您的输入。

正如您所指出的,上述假设是否成立取决于输入的长度。

由于这个陷阱,异或交换是危险的。由于它也很难阅读,并且在任何现代平台上都无法提高性能,因此这种微优化技巧已经过时,应该避免。

关于java - XOR 交换在所有情况下都等同于传统交换吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25354468/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com