Java - 交换数组
Java - swap in the array
我想交换数组中的 2 个值...
这是我的代码:
static void swap (Integer[] input, int i, int j) {
/*
* Assure indices are allright!
*/
if (i < 0 || i >= input.length)
throw new IllegalArgumentException("Incorrect i!");
if (j < 0 || j >= input.length)
throw new IllegalArgumentException("Incorrect j!");
/*
* (***) This method does not work... Why? (***)
*/
input[i] ^= input[j];
input[j] ^= input[i];
input[i] ^= input[j];
/*
* This works...
*/
/*int temp = input[j];
input[j] = input[i];
input[i] = temp;*/
}
为什么中间的方法(***)不行???
这是XOR Swap Algorithm which isn't a very effective optimization with a dynamic language like Java. Instead, I suggest that you try to Write Dumb Code的一个版本;而且你已经有了一个使用临时变量的工作交换(这对我来说似乎是最好的解决方案)所以我想我会告诉你一个正确的异或交换......最后一点,如果 [=11 确保不要尝试这个=]...
if (i == j) {
return;
}
input[i] ^= input[j];
input[j] ^= input[i];
input[i] ^= input[j];
如果您在 i 等于 j 时尝试减法(或异或),您将得到零。
它确实有效,至少有时是这样。您应该使用示例输入和输出更好地解释问题。这是一个工作测试:
import org.junit.Assert;
import org.junit.Test;
public final class Swapper
{
@Test
public void testSwap()
{
Integer[] input = {1, 2, 3};
swap(input, 0, 2);
Assert.assertArrayEquals(new Integer[]{3, 2, 1}, input);
}
@Test
public void testNoop()
{
Integer[] input = {1, 2, 3};
swap(input, 1, 1);
Assert.assertArrayEquals(new Integer[]{1, 2, 3}, input);
}
static void swap(Integer[] input, int i, int j)
{
if (i < 0 || i >= input.length)
throw new IndexOutOfBoundsException(Integer.toString(i));
if (j < 0 || j >= input.length)
throw new IndexOutOfBoundsException(Integer.toString(j));
input[i] = input[i] + input[j];
input[j] = input[i] - input[j];
input[i] = input[i] - input[j];
}
}
正如您已经发现的,当 i
和 j
相等时,您的方法将失败。通过在验证索引范围后检查该条件,可以很容易地解决这个问题。
也就是说,这是一种糟糕的交换元素的方式,因为 Java 与原始类型(如 int
及其 Object
对应物(如 [=15)一起工作的方式=].您正在创建大量 Integer
个对象实例,这可能比使用局部变量来保存传输中的元素要慢得多。
我想交换数组中的 2 个值... 这是我的代码:
static void swap (Integer[] input, int i, int j) {
/*
* Assure indices are allright!
*/
if (i < 0 || i >= input.length)
throw new IllegalArgumentException("Incorrect i!");
if (j < 0 || j >= input.length)
throw new IllegalArgumentException("Incorrect j!");
/*
* (***) This method does not work... Why? (***)
*/
input[i] ^= input[j];
input[j] ^= input[i];
input[i] ^= input[j];
/*
* This works...
*/
/*int temp = input[j];
input[j] = input[i];
input[i] = temp;*/
}
为什么中间的方法(***)不行???
这是XOR Swap Algorithm which isn't a very effective optimization with a dynamic language like Java. Instead, I suggest that you try to Write Dumb Code的一个版本;而且你已经有了一个使用临时变量的工作交换(这对我来说似乎是最好的解决方案)所以我想我会告诉你一个正确的异或交换......最后一点,如果 [=11 确保不要尝试这个=]...
if (i == j) {
return;
}
input[i] ^= input[j];
input[j] ^= input[i];
input[i] ^= input[j];
如果您在 i 等于 j 时尝试减法(或异或),您将得到零。
它确实有效,至少有时是这样。您应该使用示例输入和输出更好地解释问题。这是一个工作测试:
import org.junit.Assert;
import org.junit.Test;
public final class Swapper
{
@Test
public void testSwap()
{
Integer[] input = {1, 2, 3};
swap(input, 0, 2);
Assert.assertArrayEquals(new Integer[]{3, 2, 1}, input);
}
@Test
public void testNoop()
{
Integer[] input = {1, 2, 3};
swap(input, 1, 1);
Assert.assertArrayEquals(new Integer[]{1, 2, 3}, input);
}
static void swap(Integer[] input, int i, int j)
{
if (i < 0 || i >= input.length)
throw new IndexOutOfBoundsException(Integer.toString(i));
if (j < 0 || j >= input.length)
throw new IndexOutOfBoundsException(Integer.toString(j));
input[i] = input[i] + input[j];
input[j] = input[i] - input[j];
input[i] = input[i] - input[j];
}
}
正如您已经发现的,当 i
和 j
相等时,您的方法将失败。通过在验证索引范围后检查该条件,可以很容易地解决这个问题。
也就是说,这是一种糟糕的交换元素的方式,因为 Java 与原始类型(如 int
及其 Object
对应物(如 [=15)一起工作的方式=].您正在创建大量 Integer
个对象实例,这可能比使用局部变量来保存传输中的元素要慢得多。