3D阵列(1D平面)索引

use*_*798 5 java arrays 3d flatten multidimensional-array

我使用坐标系x(宽度),y(高度),z(深度)

只是为了清除混淆,如果有任何x和y是一个平面,我使用Z作为高程.

我将每秒访问数组数百万次,并且基准测试显示使用索引的一维数组更快,我想尽可能多地挤压效率,以便其他东西可以使用那个时间

例如,2D阵列 - > 1D阵列创建就是

Object[] oneDArray = new Object[width * height]
Run Code Online (Sandbox Code Playgroud)

并索引数组我可以使用以下.

Object obj = oneDArray[x + y * width]
Run Code Online (Sandbox Code Playgroud)

我确实在stackoverflow上找到了以下内容,但我不完全确定哪一个是正确的 如何在一维数组中"展平"或"索引"3D数组?

"正确"答案表示索引数组执行以下操作

Object[] oneDArray = new Object[width * height * depth]
Object obj = oneDArray[x + WIDTH * (y + DEPTH * z)]
Run Code Online (Sandbox Code Playgroud)

但另一个答案是说"正确"答案是错误的,并使用以下内容

Object[] oneDArray = new Object[width * height * depth]
Object obj = oneDArray[x + HEIGHT* (y + WIDTH* z)]
Run Code Online (Sandbox Code Playgroud)

读取扁平3D阵列的正确方法是什么?

Sam*_*ien 9

这是一个 Java 解决方案,可以为您提供两者:

  • 从 3D 到 1D
  • 从 1D 到 3D

我自己的微基准测试表明,1D 数组获取/设置值的速度比通过 3D 数组快 50%。

下面是我选择遍历 3D 矩阵的路径的图形说明,单元格按照遍历顺序进行编号:

2 3D矩阵的例子

转换函数:

public int to1D( int x, int y, int z ) {
    return (z * xMax * yMax) + (y * xMax) + x;
}

public int[] to3D( int idx ) {
    final int z = idx / (xMax * yMax);
    idx -= (z * xMax * yMax);
    final int y = idx / xMax;
    final int x = idx % xMax;
    return new int[]{ x, y, z };
}
Run Code Online (Sandbox Code Playgroud)

上面的代码肯定可以分解得更快,但我保留它是为了更容易理解 2 路转换;)


nio*_*nio 7

这取决于你想如何在一维数组中订购3D数据,如果你想按顺序排列索引:Z,Y,X那么你的2x2x2尺寸的3D数据将被存储如下:

index 0: [z=0,y=0,x=0]
index 1: [z=0,y=0,x=1]
index 2: [z=0,y=1,x=0]
index 3: [z=0,y=1,x=1]
index 4: [z=1,y=0,x=0]
index 5: [z=1,y=0,x=1]
index 6: [z=1,y=1,x=0]
index 7: [z=1,y=1,x=1]
Run Code Online (Sandbox Code Playgroud)

DEPTH维度对应于z,HEIGHT to y和WIDTH tox

指数计算将是:index = HEIGHT*WIDTH*z + WIDTH*y + x.

x不会乘以任何东西,因为下一个x索引就在前一个索引之后.

如果要跳过一个Y行,则必须添加整行WIDTH,在本例中为2,例如,如果您在索引1处,其中z = 0,y = 0且x = 1并且您添加WIDTH = 2要索引,你将得到索引3.只有y维度增加了1.

要从z = 0移动到z = 1,您必须跳过4个索引(查看索引列表),数字是HEIGHT*WIDTH(在此示例中为2*2).

性能

为了获得速度,最好处理您的3D数据,z,y,x坐标按顺序递增,这样您就不必经常重新计算索引.例如:

int z = 1, y=1, x=0;
int index = HEIGHT*WIDTH*z + WIDTH*y;
int data;

for(x=0;x<WIDTH;x++)
{
    Object obj = oneDArray[index+x];
}
Run Code Online (Sandbox Code Playgroud)

在理想情况下,所有数据处理都是相互独立的,您甚至不必计算索引,只需将整个索引增加一个oneDArray.预计算的可能性取决于您的使用情况.