Java-将多维数组映射到单个

时间:2015-03-13 00:19:06

标签: java arrays memory storage bitset

我发布这个与我有的另一个公开问题有关,但我认为这是值得的。

替代问题(供参考):Java Proxy Discovering Bot

基本上,我需要存储大量数据,并且可以非常快速地访问它。理想情况下,这将在无限的内存情况下工作:

boolean[][][][] sets = new boolean[256][256][256][256];
boolean get(byte[] a) {
    return sets[a[0]][a[1]][a[2]][a[3]];
}

然而,这使用了大约16gb的ram,这对我的应用来说太多了。我认为如果使用位而不是布尔值(在Java中存储为4个字节),它会将内存使用量减少到大约512MB。但是,我似乎无法正确地理解如何正确访问这些位。例如,如果您将每个地址映射为如下所示:position = a * b * c * d那么它将映射到与d * c * b * a等相同的位。

我发现这个线程涉及如何将2D数组转换为1D数组,但我似乎无法解决如何将其扩展到4D数组的问题。有谁能解释一下? Map a 2D array onto a 1D array C

2D的解决方案 - > 1D阵列:

int array[width * height];
int SetElement(int row, int col, int value)
{
  array[width * row + col] = value;  
}

我只是不确定如何将其扩展到4D - > 1D

 int array[256 * 256 * 256 * 256];
 int setElement(int a, int b, int c, int d, boolean value)
 {
    array[?????????] = value;  
 }

1 个答案:

答案 0 :(得分:1)

要回答有关将4D映射到1D的问题,如果您想象一下国际象棋棋盘,您可以通过考虑每行是否有width元素来提出2D到1D的公式,然后我首先考虑row行数,然后转到col,然后我就在width * row + col。现在想象一堆height个棋盘,并进行相同的练习,将其扩展到三维。四个维度更难,因为你无法真正想象它,但到那时你可以看到模式。

此程序显示四个维度的公式。我在这里发布了非常小的数字,但你可以使用尺寸来看看它是如何工作的。

class Dim
{
    // dimensions
    static int d1 = 2 ;   // "rows"
    static int d2 = 2;    // "cols"
    static int d3 = 3;    // "height"
    static int d4 = 2;    // the fourth dimension!

    public static void main(String[] args) {
        for (int i=0; i<d1; i++) {
            for (int j=0; j<d2; j++) {
                for (int k=0; k<d3; k++) {
                    for (int m=0; m<d4; m++) {
                        int oneD = fourDtoOneD(i, j, k, m);
                        System.out.printf("(%d, %d, %d, %d) -> %d\n", i, j, k, m, oneD);
                    }
                }
            }
        }
    }

    static int fourDtoOneD(int i, int j, int k, int m) {
        return ((d2*d3*d4) * i) + ((d2*d3) * j) + (d2 * k) + m;
    }
}


$ java Dim
(0, 0, 0, 0) -> 0
(0, 0, 0, 1) -> 1
(0, 0, 1, 0) -> 2
(0, 0, 1, 1) -> 3
(0, 0, 2, 0) -> 4
(0, 0, 2, 1) -> 5
(0, 1, 0, 0) -> 6
(0, 1, 0, 1) -> 7
(0, 1, 1, 0) -> 8
(0, 1, 1, 1) -> 9
(0, 1, 2, 0) -> 10
(0, 1, 2, 1) -> 11
(1, 0, 0, 0) -> 12
(1, 0, 0, 1) -> 13
(1, 0, 1, 0) -> 14
(1, 0, 1, 1) -> 15
(1, 0, 2, 0) -> 16
(1, 0, 2, 1) -> 17
(1, 1, 0, 0) -> 18
(1, 1, 0, 1) -> 19
(1, 1, 1, 0) -> 20
(1, 1, 1, 1) -> 21
(1, 1, 2, 0) -> 22
(1, 1, 2, 1) -> 23