簡體   English   中英

如何動態增加2D數組的大小

[英]How to dynamically increase size of a 2D array

如果我知道有多少個元素,我已經知道如何制作固定數組。 例如,對於7個元素,我會執行類似int array [2] [4]的操作。

但是,如果我在開始時有0個元素(這意味着數組在開始時將為空)並想在程序運行時增加數組大小怎么辦?

基本上,如何添加新的行或列?

ArrayList文檔和示例 請享用!

特別:

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1); // Add 1 to the list.

注意new int[2][4]int[]的數組; int[]數組中的int[][]數組最初都具有相同的長度,但是不要求它們保持相同的長度。 可以將int[][]數組的任何元素重新分配為具有不同長度的int[] ,而完全不影響其他元素。 “行”和“列”的概念是更高級別的概念,Java數組不支持。

使用ArrayList作為其他答案表明不會改變這一點。 此外,由於將int值自動裝箱為Integer對象,根據使用ArrayList ,可能會產生相當大的開銷。

如果要保留數據的矩形形狀,建議您定義一個Matrix類,使所有維保持一致。 (或者,也許更好,將二維數組線性化為一維數組,並使用內部存儲的行和列大小進行適當的下標計算。或者,也許最好,使用編寫良好的矩陣庫(例如JAMA或基本數組) Trove之類的收藏庫。)

編輯這是簡單矩陣類的開始,該類在內部使用線性存儲方案並允許調整矩陣大小。 數據以行優先順序存儲,索引基於0。

public class IntMatrix {
    private int rows;
    private int cols;
    private int[] data;

    /**
     * Allocate a matrix with the indicated initial dimensions.
     * @param cols The column (horizontal or x) dimension for the matrix
     * @param rows The row (vertical or y) dimension for the matrix
     */
    public IntMatrix(int cols, int rows) {
        this.rows = rows;
        this.cols = cols;
        data = new int[cols * rows];
    }

    /**
     * Calculates the index of the indicated row and column for
     * a matrix with the indicated width. This uses row-major ordering
     * of the matrix elements.
     * <p>
     * Note that this is a static method so that it can be used independent
     * of any particular data instance.
     * @param col The column index of the desired element
     * @param row The row index of the desired element
     * @param width The width of the matrix
     */
    private static int getIndex(int col, int row, int width) {
        return row * width + col;
    }

    public int get(int col, int row) {
        return data[getIndex(col, row, cols)];
    }

    public void set(int col, int row, int value) {
        data[getIndex(col, row, cols)] = value;
    }

    /**
     * Resizes the matrix. The values in the current matrix are placed
     * at the top-left corner of the new matrix. In each dimension, if
     * the new size is smaller than the current size, the data are
     * truncated; if the new size is larger, the remainder of the values
     * are set to 0.
     * @param cols The new column (horizontal) dimension for the matrix
     * @param rows The new row (vertical) dimension for the matrix
     */
    public void resize(int cols, int rows) {
        int [] newData = new int[cols * rows];
        int colsToCopy = Math.min(cols, this.cols);
        int rowsToCopy = Math.min(rows, this.rows);
        for (int i = 0; i < rowsToCopy; ++i) {
            int oldRowStart = getIndex(0, i, this.cols);
            int newRowStart = getIndex(0, i, cols);
            System.arraycopy(data, oldRowStart, newData, newRowStart,
                colsToCopy
            );
        }
        data = newData;
    }

    . . .
}

這就是為什么無法調整大小的原因 無論是1維還是20維,數組的每個維都作為連續的數據行分配在某處,任何此類序列之后的存儲空間都是公平的,可供其他變量和數據使用。 例如,ary = new int [4]可以這樣表示在內存中:

| ary[0] | ary[1] | ary[2] | ary[3] | otherNearbyData1 | otherData2 | ...

由於數組數據之后可能還會有其他變量,因此您必須分配一個具有所需大小的新數組,並將所有元素從舊數組復制到新數組。 一種策略是,每次達到100%的容量時,分配大小就會增加一倍,以獲取固定的攤銷時間復雜度。 這或多或少是ArrayList所做的,但是正如Peter Lawrey指出的那樣,這浪費了大量的空間。

根據您的需要的一種替代方法可能是LinkedList,其中每個數據元素都被單獨分配,並包含指向下一個/上一個元素的指針。 盡管鏈表非常緊湊(沒有浪費的空間)並且可以增長到任意大小,但是它具有兩個主要缺點:

  • 沒有隨機訪問權限(您只能從一個元素遍歷到下一個/上一個元素)。
  • 時間效率極低-跨越地址空間只是為了到達每個下一個元素,這完全消除了CPU緩存的麻煩。

編輯:再三考慮...即使2D鏈表是可能的,但您需要多個維度的事實可能意味着順序遍歷對您來說還不夠。 我的錯。

創建一個更大的新數組,復制現有元素並添加要添加的元素。 您可以使用類似ArrayList的方法,但這很昂貴,並且將使用大約4倍的內存。 如果您不想自己調整數組的大小,我會考慮使用TDoubleArrayList

Java數組可以動態創建,但不能動態擴展。 您可能想要查看VectorArrayList的其他建議。

但是,請記住,在您的示例中,您創建了一個矩陣,這是稍有不同的事情。

當然,您可以使用Collections(例如ArrayList),但是如果要使用2D矩陣,則可以“即時”創建具有不同大小的行。 例如,以下示例創建“三角形”矩陣:

int[][] matrix = new int[3][];
int count = 0;
for (int i = 0; i < 3; i++) {
    matrix[i] = new int[i];
    for (int j = 0; j < i; j++) {
        matrix[i][j] = ++count;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM