Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java variable number of dimensions in an array

Is there a possible way to create an array with a variable number of dimensions?

For example,

int x = 3;
// becomes
int[][][] array = new int[3][3][3];

//and
int y = 4;
//becomes
int[][][][] xray = new int[4][4][4][4];

Part of the reason my examples are so indirect is because I have no idea how one would do something like this.

If I have a variable I would like to create an array with the same number of dimensions as said variable

like image 401
Mazino Avatar asked Aug 24 '26 11:08

Mazino


2 Answers

You can't do this directly, but you can simulate it with a 1-dimensional array.

Suppose you have a 2-dimensional array with 3 rows and 4 columns. You could implement this as an array of 12 elements, and write a get routine to get the A[i,j] element like this:

int[] A = new int[12];

int get(int i, int j) {
    return A[4 * i + j];
}

Of course you could write a set method to set an element of the array in the same way.

Moving on to a 3-dimensional array whose dimensions are 3x4x5, you could do something similar:

int[] A = new int[60];

int get(int i, int j, int k) {
    return A[4*5*i + 5*j + k];
}

or a 4-dimensional 3x4x5x6 array:

int[] A = new int[360];

int get(int i, int j, int k, int m) {
    return A[4*5*6*i + 5*6*j + 6*k + m];
}

And so on... you should be able to see the pattern.

Once you've grasped that, it shouldn't be hard to write a class for an array that takes a variable number of dimensions. The get and set methods could take an int... parameter for a variable number of indexes, and the constructor could similarly take an int... to specify the dimensions. The class would have a private 1-dimensional array whose length is the product of all the dimensions. The get and set methods should check each index to make sure it's >= 0 and less than the corresponding dimension, and throw an exception otherwise.

This is how "true" multi-dimensional arrays are implemented under the hood in most languages that support them (Java is not one of those; it only has 1-dimensional arrays whose elements can be references to other 1-dimensional arrays). It's called "row-major order". See https://en.wikipedia.org/wiki/Row-_and_column-major_order for more information (including the generalized formula).

like image 89
ajb Avatar answered Aug 27 '26 02:08

ajb


Short answer you can't. Reason: there is no instance in the world of maths where such a construct could be optimum for anything so the Prophets (K&R and all the good ppl who invent code) left such to the developer who needs it.

But here is my 2 cents: I assume you want to initialize your engine...

engine.init(n);

where n is your dimension. Then be able to put and get things from it.

engine.get(a1,a2,a3,...);
engine.put(val,a1,a2,a3...);

Consider a class like this

public class Engine{
private HashMap<Integer[],Object> storage;
private int dimension=1;
private set<integer[]> keys;
public void init(int n){
dimension=n;
//other initialization task;
}

public Object get(int... a){//use var args
integer[] key=findInkeySet(a);
return storage.get(key);
}

public void put(Object val, int... a){
keys.add(a);
storage.put(a,val);
}
}

ofcause there is need for exception handling and all the other generic coding stuf

like image 33
Comfort Chauke Avatar answered Aug 27 '26 04:08

Comfort Chauke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!