当使用奇数立方3d数组(3x3x3,5x5x5,7x7x7等)时,返回该数组的2d切片的最有效方法是,给定切片定向的轴和值用于确定切片沿该轴的相关位置?
答案 0 :(得分:1)
由于这是一个非常有趣的主题,我一直在寻找答案。我想你可能会对Mark Byers的方法感到满意:
Mark没有将其存储在3D数组中,而是采用了一种非常好的方法来处理一维数组。
经过一番尝试后,我想出了完整的立方体,希望这能满足你的需求:
public class Cube {
int w, h, d;
int[] cube;
public Cube(int w, int h, int d) {
this.w = w;
this.h = h;
this.d = d;
System.out.println("cube: w" + w + ", h" + h + ", d" + d + " = " + (w * h * d));
cube = new int[w * h * d];
}
int getCubeValue(int x, int y, int z) {
return cube[x * h * d + y * d + z];
}
void setCubeValue(int x, int y, int z, int value) {
System.out.println("value " + (x * h * d + y * d + z) + ": x" + x + ", y" + y + ", z" + z + " = " + value);
cube[x * h * d + y * d + z] = value;
}
int[] xSlice(int x) {
int[] slice = new int[h * d];
for(int y = 0; y < h; y++) {
for(int z = 0; z < d; z++) {
slice[y * d + z] = getCubeValue(x, y, z);
}
}
return slice;
}
int xSliceValue(int[] slice, int y, int z) {
return slice[y * d + z];
}
int[] ySlice(int y) {
int[] slice = new int[d * w];
for(int z = 0; z < d; z++) {
for(int x = 0; x < w; x++) {
slice[z * w + x] = getCubeValue(x, y, z);
}
}
return slice;
}
int ySliceValue(int[] slice, int x, int z) {
return slice[z * w + x];
}
int[] zSlice(int z) {
int[] slice = new int[w * h];
for(int x = 0; x < w; x++) {
for(int y = 0; y < h; y++) {
slice[x * h + y] = getCubeValue(x, y, z);
}
}
return slice;
}
int zSliceValue(int[] slice, int x, int y) {
return slice[x * h + y];
}
}
假设你创建了一个像new Cube(3, 3, 3)
这样的多维数据集,cube.getCubeValue(2, 2, 2)
可以接近最后一个值,因为它从0开始。
答案 1 :(得分:1)
我认为您可以选择三个选项,具体取决于您希望切片方法的输入和输出是什么:
int[][] ArrayUtils.slice(int[][][] cube, int axis, int sliceIndex)
SomeKindOf2DimArrayClass ArrayUtils.slice(int[][][] cube, int axis, int sliceIndex)
SomeKindOf2DimArrayClass slice(int axis, int sliceIndex)
就你的界面而言。
实现方面,如果你使用原始数组,那么你没有太多选择,只能做一些“繁重的工作” - 为siice建立一个2d数组 - 至少对于第3轴。对于第一个轴,您只需要使用其中一个2d阵列(即result = Arrays.copyOf(cube[sliceIndex])
,或者如果您感觉活泼,甚至只需使用该引用);对于第二个轴,您将拥有类似
for(int i=0; i<cube.length; i++) {
myAllocated2dArray[i] = Arrays.copyOf(cube[i][sliceindex])
}
如果你正在使用一个对象,你有很多选择,从我刚刚描述的那些到@Aquillo在his answer中建议的那些,到原始数组的O(1)空间包装器getter方法。
通过阅读C language FAQs中关于类似问题的答案,您可能会对已经建议的两个实现有所启发,其中指针(引用)的使用是明确的: