【问题标题】:Performance of copying/merging arrays in JavaJava中复制/合并数组的性能
【发布时间】:2014-02-06 10:23:44
【问题描述】:

我需要在 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]

【问题讨论】:

  • 告诉我们如何存储矩阵以及合并后应该得到什么结果。那样帮助你会更简单。
  • 请看我的编辑。谢谢。
  • 目前还不清楚,你是如何在内存中组织的?你使用一维数组,它有由行/列组成的矩阵,还是你使用二维数组? (这对任务不利。)
  • @marc wellman:请看我的编辑。
  • @DenisKulagin:我也有同样的看法。

标签: java arrays performance matrix


【解决方案1】:
use System.arrayCopy(src,src start index,destn,destn start index,destn length)

【讨论】:

    【解决方案2】:

    尝试使用 ArrayUtils

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

    【讨论】:

      【解决方案3】:

      请务必使用原生 System.arraycopy。它具有 O(n) 复杂度,但由于处理器级支持此类操作,因此运行速度非常快。

      java.util.Arrays.copyOf 也可以 - 它是使用 System.arraycopy 实现的。

      【讨论】:

        【解决方案4】:

        我不认为你可以在这个任务中找到一个 O(1) 算法。

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

        【讨论】:

          【解决方案5】:

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

          你不能得到一个 O(1) 操作来复制一个数组。唯一这样的方法是创建一个引用:Object[] newArray = oldArray。这不会复制旧数组。它只是将newArray 指向oldArray。要理解为什么 O(1) 的深拷贝是不可能的,请从计算机层面考虑:

          当您创建一个数组时,会为该数组留出一块内存。要复制每个元素,计算机必须遍历数组的每个部分并将其复制到其他地方(更确切地说,将每个位复制到其他地方)。对于单个元素数组,这只需要一次操作。对于一个 5 元素数组,它需要 5 次操作。显然,对于 n 元素数组,这需要 n 操作。

          因此复制一个数组的时间复杂度有一个下界O(n)

          【讨论】:

            【解决方案6】:

            如果您需要一个密集矩阵,那么分配一大块大小为 M x N 的 array[] 并将其包装在一个 Matrix 类中会更容易,该类可以将 matrix(r, c) 转换为 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),其中矩阵的N = ROWS * COLS

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-03-03
              • 1970-01-01
              • 2019-04-18
              • 1970-01-01
              • 2021-09-29
              • 2019-12-17
              • 1970-01-01
              • 2018-10-11
              相关资源
              最近更新 更多