在Java中复制/合并数组的性能

时间:2014-01-17 07:14:35

标签: java arrays performance matrix

我需要在Java中合并两个双矩阵,我知道

在课程public static double[] copyOf(double[] original, int newLength)

中定义的

java.util.Array

但是我担心运行时因为我需要运行时最有效的结果,当然理想情况下是O(1)但是我猜操作是O(n)还是更差?

任何人都可以提供建议吗?


补充

我刚刚意识到这种方法仅适用于向量(double [])并且需要矩阵。任何想法都表示赞赏。

我想要达到的目标是:

m1m2为双矩阵,例如

m1 =

[1,2,3]
[4,5,6]
[7,8,9]

m2 =

[3,2,1]
[6,5,4]

然后我想要一个双矩阵m3

[1,2,3]
[4,5,6]
[7,8,9]
[3,2,1]
[6,5,4]

6 个答案:

答案 0 :(得分:1)

use System.arrayCopy(src,src start index,destn,destn start index,destn length)

答案 1 :(得分:1)

尝试使用 ArrayUtils

int m[] = (int [])ArrayUtils.addAll(x,y);

答案 2 :(得分:1)

确保使用原生 System.arraycopy 。它具有O(n)复杂性,但由于处理器级别支持此类操作,因此工作速度非常快。

java.util.Arrays.copyOf 也会这样做 - 它是使用System.arraycopy实现的。

答案 3 :(得分:0)

我认为你不能找到一个O(1)算法这个任务。

我几乎可以肯定你的复杂性将是O(n)。

答案 4 :(得分:0)

如果你需要一个密集矩阵,那么分配一大块大小为M x N的array[]并将其包装在一个Matrix类中会更容易,它可以将矩阵(r,c)转换为{{1 }}

这样,您只需对内部array[r*C + c]进行一次数组复制操作。

这样的事情:

编辑:使用array[]添加了行主矩阵连接:

System.arraycopy()

<强>输出

package example;

import java.util.Arrays;
import java.util.Random;

public class Matrix {
    private double[] array;
    int R;
    int C;

    Matrix(int R, int C) {
        this.R = R;
        this.C = C;
        this.array = new double[R * C];
    }

    Matrix(double[] array, int R, int C) {
        this.R = R;
        this.C = C;
        this.array = array;
    }

    Matrix(Matrix that) {
        this.R = that.R;
        this.C = that.C;
        array = Arrays.copyOf(that.array, that.array.length);
    }

    public void set(int r, int c, double value) {
        assert (r >= 0 && r < R);
        assert (c >= 0 && c < C);
        array[C * r + c] = value;
    }

    public double get(int r, int c) {
        assert (r >= 0 && r < R);
        assert (c >= 0 && c < C);
        return array[C * r + c];
    }

    public static Matrix concatRows(Matrix m1, Matrix m2) {
        double[] array = concat(m1.array, m2.array);
        Matrix m = new Matrix(array, m1.R + m2.R, m1.C);
        return m;
    }

    private static double[] concat(double[] array2, double[] array3) {
        int aLen = array2.length;
        int bLen = array3.length;
        double[] C = new double[aLen + bLen];
        System.arraycopy(array2, 0, C, 0, aLen);
        System.arraycopy(array3, 0, C, aLen, bLen);
        return C;
    }

    public void print() {
        for (int r = 0; r < R; r++) {
            for (int c = 0; c < C; c++) {
                double v = get(r, c);
                System.out.print(String.format("%.3f ", v));
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void main(String[] args) {
        double[] a1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        Matrix m1 = new Matrix(a1, 3, 3);
        m1.print();

        double[] a2 = { 3, 2, 1, 6, 5, 4 };
        Matrix m2 = new Matrix(a2, 2, 3);
        m2.print();

        Matrix m3 = Matrix.concatRows(m1, m2);
        m3.print();
    }
}

基本上,除非您能确保该矩阵是不可变的,否则您只能求助于整个矩阵的深层复制。因此,订单仍为1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 3.000 2.000 1.000 6.000 5.000 4.000 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 3.000 2.000 1.000 6.000 5.000 4.000 ,其中矩阵为O(N)

答案 5 :(得分:0)

要复制数组,请使用System#arrayCopyjava.util.Arrays#copyOf

您无法获得复制数组的O(1)操作。唯一的方法是创建一个引用:Object[] newArray = oldArray。这不会复制旧数组。它只是将newArray指向oldArray。要理解为什么O(1)的深层副本是不可能的,请在计算机级别上考虑它:

创建数组时,会为该数组留出一块内存。要复制每个元素,计算机必须遍历数组的每个部分并将其复制到其他位置(相反,每个位并将其复制到其他位置)。使用单个元素数组,这只需要一个操作。使用5个元素数组,需要5个操作。显然,对于n元素数组,这需要n次操作。

因此,复制数组的时间复杂度具有O(n)

的下限