关于反向阵列的问题

时间:2010-06-16 10:14:27

标签: java algorithm

我们知道算法如何反转n个整数的数组

 for (int i=0;i<n/2;i++){
  swap(a[i],a[n-1-i]):
}

这种方法是否更好地根据算法的速度而不是因为使用xor的交换比其他方法更快 这是代码

public class swap {

    public static  void main(String[]args){
        int a[]=new int[]{2,4,5,7,8,11,13,12,14,24};
        System.out.println(" array at the begining:");
        for (int i=0;i<a.length;i++){
            System.out.println(a[i]);
        }

        for (int j=0;j<a.length/2;j++){
            a[j]^=a[a.length-1-j];
            a[a.length-1-j]^=a[j];
            a[j]^=a[a.length-1-j];
        }
        System.out.println("reversed array:");
        for (int j=0;j<a.length;j++){
            System.out.println(a[j]);
        }
    }
}

结果:

array at the begining:
2
4
5
7
8
11
13
12
14
24
reversed array:
24
14
12
13
11
8
7
5
4
2

5 个答案:

答案 0 :(得分:3)

这是完全相同的算法,但您使用XOR交换方法而不是使用临时变量的显式交换。 XOR交换方法只是一种新颖性,如果有正当理由,它的使用很少。坚持简单明了的实施,然后你可以专注于更重要的事情。

答案 1 :(得分:1)

我使用XOR和临时做了一些测试:XOR慢大约两倍 代码如下:

public class Swap {

    private static void swap1(int[] a) {
        int half = a.length / 2;
        Timer timer = new Timer();
        for (int repeat = 201; repeat > 0; repeat--) {
            for (int i = 0, j = a.length-1; i < half; i++,j--) {
                a[i] ^= a[j];
                a[j] ^= a[i];
                a[i] ^= a[j];
            }
        }
        Times times = timer.times();
        System.out.println("swap1: " + times);
    }

    private static void swap2(int[] a) {
        int half = a.length / 2;
        Timer timer = new Timer();
        for (int repeat = 201; repeat > 0; repeat--) {
            for (int i = 0, j = a.length-1; i < half; i++,j--) {
                int t = a[i];
                a[i] = a[j];
                a[j] = t;
            }
        }
        Times times = timer.times();
        System.out.println("swap2: " + times);
    }

    public static  void main(String[]args){
        int a[] = new int[102400];
        for (int i = 0; i < a.length; i++) {
            a[i] = i;
        }
        System.out.println(Arrays.toString(Arrays.copyOf(a, 10)) + "..." + Arrays.toString(Arrays.copyOfRange(a, a.length-10, a.length)));
        swap1(a);
        System.out.println(Arrays.toString(Arrays.copyOf(a, 10)) + "..." + Arrays.toString(Arrays.copyOfRange(a, a.length-10, a.length)));
        swap2(a);
        System.out.println(Arrays.toString(Arrays.copyOf(a, 10)) + "..." + Arrays.toString(Arrays.copyOfRange(a, a.length-10, a.length)));
        swap1(a);
        swap2(a);
    }
}

一些典型的结果:

java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Server VM (build 16.3-b01, mixed mode)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]...[102390, 102391, 102392, 102393, 102394, 102395, 102396, 102397, 102398, 102399]
swap1: elapsed=0,068    cpu=0,063    user=0,063    [seconds]
[102399, 102398, 102397, 102396, 102395, 102394, 102393, 102392, 102391, 102390]...[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
swap2: elapsed=0,035    cpu=0,031    user=0,031    [seconds]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]...[102390, 102391, 102392, 102393, 102394, 102395, 102396, 102397, 102398, 102399]
swap1: elapsed=0,063    cpu=0,063    user=0,063    [seconds]
swap2: elapsed=0,023    cpu=0,031    user=0,031    [seconds]

(每次调用两次以消除一些启动问题)

答案 2 :(得分:0)

  

使用xor交换更快

在Java客户端JVM上,它在消除边界检查方面不那么积极,那么没有临时值的XORing比使用单个临时值要花费几乎两倍的时间来反转数组。如果将值移动到临时值以避免重复边界检查,则会使用临时变量获得接近速度的值,但是您没有避免使用临时变量。

这使用System.nanoTime,对于具有临时值的版本,给出16或17毫秒,对于我的机器上具有XOR的版本,给出30毫秒。所有其余的循环都是相同的。使用XOR的临时值约为19ms,因此推断差异是由于XOR版本中的额外数组访问是合理的。

public class XorTest {
    static final int[] array = new int[10000000];

    static void runTest (String name, Runnable test) {
        final long start = System.nanoTime();

        test.run();

        final long finish = System.nanoTime();

        System.out.println (name + ": " + ( finish - start ) / 1000000 + "ms");
    }

    public static void main ( String...args ) {
        if (args.length == 0 || "xor".equals(args[0]))
            runTest(
                "xor",
                new Runnable () {
                    @Override
                    public void run () {
                        for (int i = 0, max = array.length / 2, j = array.length - 1; i < max; ++i,--j) {
                            array[i] ^= array[j];
                            array[j] ^= array[i];
                            array[i] ^= array[j];
                        }
                    }
                });
        else if ("tmp".equals(args[0]))
            runTest(
                "tmp",
                new Runnable () {
                    @Override
                    public void run () {
                        for (int i = 0, max = array.length / 2, j = array.length - 1; i < max; ++i, --j) {
                            int tmp = array[i];
                            array[i] = array[j];
                            array[j] = tmp;
                        }
                    }
                });
        else if ("xor+tmp".equals(args[0]))
            runTest(
                "xor+tmp",
                new Runnable () {
                    @Override
                    public void run () {
                        for (int i = 0, max = array.length / 2, j = array.length - 1; i < max; ++i, --j) {
                            int a = array[i];
                            int b = array[j];
                            a^=b;
                            b^=a;
                            a^=b;
                            array[i] = a;
                            array[j] = b;
                        }
                    }
                });
    }
}

答案 3 :(得分:0)

在这里,最好!!

2.0

答案 4 :(得分:-1)

xor swap方法适用于整数,但每次迭代计算a.length-1-j 3次就是杀了你。

相关问题