Разряд набора массива во времени выполнения

Я задавался вопросом, что самый простой путь будет состоять в том, чтобы реализовать массив, кто разряд, указан во времени выполнения.

Пример я работаю над хранилищами массив булевых значений для узлов решетки, и я хочу, чтобы пользователь смог к, выбрал, сколько пространственных размеров модель использует во времени выполнения.

Я посмотрел на Array.newInstance () метод:

dimensionOfSpace = userInputValue;  // this value comes from GUI or whatever
int latticeLength = 5;  // square lattice for simplicity

int[] dimensions = new int[dimensionOfSpace];
for(int i = 0; i < l.length; i++) l[i] = length; 
Object lattice = Array.newInstance(boolean.class, dimensions);

Но доступ к этим значениям в любом виде пути, кажется, требует ужасно медленных методов, таких как рекурсивное использование Array.get, пока возвращенное значение больше не является массивом, т.е. использующий isArray ().

Я пропускаю очевидное решение здесь? Я хотел бы смочь получить доступ к значениям, в некотором роде подобным нечто [я] [j] [k].

5
задан John Paul 23 August 2013 в 01:30
поделиться

4 ответа

Похоже, что вы ищете, это какой-то способ объявить, сколько измерений имеет массив во время выполнения. Я не знаю, как это можно сделать с использованием многомерного арайлиста или любой многомерной структуры, где вы должны указать размерность при компиляции.

Единственный ответ, который я вижу, это использовать простой линейный массив, завернутый в класс, который преобразует многомерную координату в и из его положения в базовом массиве. Это в основном, как такие языки, как C хранилищ многомерных массивов, используя один непрерывный кусок памяти.

Код будет выглядеть что-то подобное:

import java.util.*;

class MultiArray<T>{
    private int[] dimensions;
    private Object[] array;

    public MultiArray(int ... dimensions){
        this.dimensions=dimensions;
        //Utils.product returns the product of the ints in an array
        array=new Object[Utils.product(dimensions)];
    }

    public void set(T value, int ... coords){
        int pos=computePos(coords); 
        array[pos]=value;
    }

    public T get(int ... coords){
        int pos=computePos(coords);
        return (T)(array[pos]);
    }

    private int computePos(int[] coords){
        int pos=0;
        int factor=1;
        for (int i=0;i<coords.length;i++){
            pos+=factor*coords[i];
            factor*=dimensions[i];
        }
        return pos;
    }
}

class Main{
    public static void main(String args[]){
        MultiArray<Integer> m=new MultiArray<Integer>(new int[]{5,4,3}); 
        Random r=new Random();

        for(int i=0;i<5;i++)
            for(int j=0;j<4;j++)
                for(int k=0;k<3;k++)
                    m.set(r.nextInt(),i,j,k);
        for(int i=0;i<5;i++){
            for(int j=0;j<4;j++){
                for(int k=0;k<3;k++)
                    System.out.print(m.get(i,j,k)+" ");     
                System.out.println("");
            }
            System.out.println("\n");
        }
    }
}

class Utils{
    public static int product(int...a){
        int ret=1;
        for (int x:a) ret*=x;
        return ret;
    } 
}
5
ответ дан 13 December 2019 в 05:35
поделиться

Оформить заказ Java Collections . Он содержит класс под названием ArrayList , который растет по мере необходимости.

Одномерный список

A = новый ArrayList ();

Двумерный

список <Список > B = новый список <Список > ();

Трехмерные

Список <Список <список >> C = новый список <Список <Список >> ();

и вы получите доступ к элементу как c. get (i) .get (j) .get (k) вместо c [i] [j] [k] , как в 3D-массиве. Или еще лучше, оберните его в свой собственный класс и используйте метод Get () . Таким образом, он становится:

C.get (i, j, k) ;

Редактировать :

, чтобы иметь многомерный список глубины N, удалить Boolean Тип индикатора и просто создайте списки как

List level1 = new ArrayList();
List level2 = new ArrayList();
List level3 = new ArrayList();
level1.add(level2);
level2.add(level3);

и так далее ..

3
ответ дан 13 December 2019 в 05:35
поделиться

Я сделал быстрый поиск Google для "Java Tensor", который придумал DJEP , может ли это быть чем-то, что соответствует вашему законопроекту?

1
ответ дан 13 December 2019 в 05:35
поделиться

Я собираюсь использовать термин «ранг», чтобы означать «количество измерений» в вашем массиве. Таким образом, вектор имеет ранг 1, матрица имеет ранг 2 и так далее. Вы уже приняли ответ, что по вашему входу не совсем то, что вы хотите. Вот альтернатива урегулированию менее чем меньше:

напомним, что память компьютера по существу линейна, и что делает компилятор, когда он дает вам массивы, фактически заботится о преобразовании экспрессии индекса в линейный адрес. Это проще, чтобы подумать, если вы предполагаете, что все массивы находятся в смежной памяти, не всегда правда. Предположим, что вы делаете декларацию, такую ​​как Array_of_Type [10] [10] [10], то есть он имеет 1000 элементов. Затем элемент в положении [3] [5] [4] IS (мои массивы индексируются из 1 не 0 - измените суммы, которые следуют, если вы хотите) на местоположении Baseaddress + 354 * Size_of_Element_of_type.

Я ожидаю, что вы знаете, куда я собираюсь на это ...

во время выполнения ваша программа предлагает список целых чисел от пользователя. Каждое целое число определяет размер одного из измерений массива, количество целых чисел определяет ранг массива. Ваша программа делает некоторые мультипликации, и вы выделяете вектор правой длины. Хорошо, вы должны написать функции индексации и де-индексации, но они должны быть довольно простыми.

ET VOILA У вас есть массив, чье звание устанавливается во время выполнения.

3
ответ дан 13 December 2019 в 05:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: