2013-04-13 2 views
2

При работе с нечетным кубическим трехмерным массивом (3x3x3, 5x5x5, 7x7x7 и т. Д.), Что было бы самым эффективным способом вернуть 2d-срез этого массива, данный ось, на которую нужно ориентировать срез, и значение, которое необходимо использовать для определения соответствующего положения среза вдоль этой оси?Java 3D-массив: сохранение куба, извлечение куска куба

+0

Можете ли вы уточнить, что вы подразумеваете под «осью» и «срезом»? Согласуются ли оси с направлениями x-y-z? Если это не так, что вы хотите вернуть в случае, когда ваше сечение не прямоугольное? –

+0

Да, ось будет, скажем, int 0/1/2, которая будет соответствовать оси x/y/z, центрированной в середине исходного массива, тогда это значение может быть смещением от центра 0/+ 1/-1/etc или сбоку. В этом случае срез будет представлять собой массив 2d, ориентированный перпендикулярно указанной оси и смещенный на значение. – Shukaro

ответ

1

Я думаю, что у вас есть выбор из трех опций, чтобы сделать, в зависимости от того, что вы хотите, чтобы ваш вход и выхода методы нарезания быть:

  • нарезка работает на примитивном многомерном массиве Java, производит примитивный многомерный массив Java, например:

int[][] ArrayUtils.slice(int[][][] cube, int axis, int sliceIndex)

  • нарезка работает на примитивном многомерный массив Java, микрофильтр ES объект с геттерами, например:

SomeKindOf2DimArrayClass ArrayUtils.slice(int[][][] cube, int axis, int sliceIndex)

  • нарезка использует не-примитивные массивы как в качестве входа и выхода, а также представляет собой способ такого класса:

SomeKindOf2DimArrayClass slice(int axis, int sliceIndex)

Это касается вашего интерфейса.

Реализация, если вы используете примитивные массивы, тогда у вас нет большого выбора, кроме как сделать «тяжелый подъем» - построить 2d-массив для siice - по крайней мере для 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) -пространственные обертки для исходных массивов с методами геттера.

Вы можете получить вдохновение в отношении двух реализаций уже предложенных, прочитав ответ относительно аналогичного вопроса в C language FAQs, где использование указателей (ссылок) является явным:

How can I use statically- and dynamically-allocated multidimensional arrays interchangeably when passing them to functions?

1

Поскольку это довольно интересный предмет для меня, я тоже искал ответ. Я думаю, вам может быть повезло с подходом Mark Byers:

Вместо того, чтобы хранить это в 3D-массиве, Mark имеет очень хороший подход к использованию массива 1D.

После некоторых попыток я придумал полный куб, надеюсь, что это люксов:

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), так как он начинается нуль.

Смежные вопросы