0

So what im trying to do is fold an arbitrary sized multidimensional array, to a bigger dimensional randomly, for example:

String [][] myArray = new String[5][5]

would transform to :

String [][][][][] transformedArray = new String [10][10][10][10][10]

I am inputting the data from the previous array into the new array and then filling up the new array with random data which is bogus data. My problem is creating then an access function that will allow me to get the correct data from the new array, would anyone be able to give me any pointers to how i would go abouts doing this?

Alan Liang
  • 13
  • 6
  • How do you want to put 25 things into 10,000 spaces? – Andy Turner Mar 16 '16 at 10:52
  • @AndyTurner in a way the 25 items is distributed evenly so its easier to create an access function, however not simply just by putting the 25 items into the first 25 spaces, if that made sense? – Alan Liang Mar 16 '16 at 11:16
  • So if I understand correctly, you want to put the data from the old array into a bigger array full of random data and still be able to recover which data is random and which is from the original array ? And the dimension of the new array is random ? – Asoub Mar 16 '16 at 12:44
  • @Asoub yes in a sense yes, however, i would first generate the new array, then input the data from the old array into the new one, in some specific order then, fill it up with random data, however im wondering if there is a way in which i can do this, so i can have an access function which would let me retrieve the original data, does that make sense ? – Alan Liang Mar 16 '16 at 12:56
  • Yeah I think I get it, but it seems really complicated. Is M and N fixed or is dynamic ? As I see it, one way to do it is to consider that both arrays are a one-dimension arrays, and use this one-dimension array to go from the old array to the new one. Using your example and "linear" transformation, oldArray[2][3] would be the 5+5+3 : 13th element if it was a one-Dimension array and transformedArray[2][1][3][8][4] would be ... well I'm trying to figure that out for the moment. – Asoub Mar 16 '16 at 13:15
  • M and N are fixed, they dont change in size after they are initialised. Im not 100% understanding the why oldArray[2][3], would be 5+5+3? Could you explain this more? thank you so much though for helping out :D – Alan Liang Mar 16 '16 at 13:37
  • I think I got it, writing a full answer. – Asoub Mar 16 '16 at 13:55

1 Answers1

1

You need to transfer your N-dimension array to a one-dimension array. For example, if you use String [][] myArray = new String[5][5], String[] oneDimArr[] = new String[5*5] then myArray[0][3] would be oneDimArr[0*5+3], and myArray[2][4] would be oneDimArr[2*5+4].

Just like if you took each line of a matrix and stuck them into one consecutive big line.

Another example: my3Darr[][][] = new String [7][7][7]; and OneDimArr[] = new String[7*7*7] so, my3Darr[4][5][2] would be oneDimArr[4*7*7+5*7+2].

You can use this on myArray and transformedArray. You'll have one array of length 25 and one array of length 10000. Then transfert the data as you wish. For example multiply by 4000 (which is 10000/25): 1D_myArray[i] would be 1D_transformedArray[i*4000]. Now you just reverse the process: put 1D_transformedArray as transformedArray.

You won't really need to go through a 1D array for both array in your final code, you'll just need to get the methods from 2D to 5D indexes, but you'll go from 2D index to 1D index, then from this 1D index through your function (the "i*4000" or whatever you want), then from this new 1D index to your 5D index.

Exemple:

String [][] myArray = new String[5][5]
String [][][][][] transformedArray = new String [10][10][10][10][10]

Postion/index from 2D to 1D [2][4] => [14]

Index transformation14*4000 => 56.000

From 1D to 5D 56.000 => [k,l,m,n,o] with `j=56.000, k = j/10^4, l=(j%10^4)/10^3, m=(j%10^3)/10^2, n=(j%10^2)/10^1, o=j%10^1/10^0.

Well for the "from 1-dimension to N-dimension" algorithm I'm not that sure but I hope you get the idea (Algorithm to convert a multi-dimensional array to a one-dimensional array might hold other exmplanations)

Not sure but you might need this: Getting unknown number of dimensions from a multidimensional array in Java

Also watch out for overflow, int might not be big enough to contains the 1D index, be carefull with that, use long.

EDIT: had to try it, so here it goes:

 public static void main(String[] args) {
        //Easy to calculate
        int[] coords = {4,5,2};
        System.out.println("out1:"+indexFromNDto1D(coords,7,3)); //233
        System.out.println("out2:"+Arrays.toString(indexFrom1DToND(233,7,3))); //{4,5,2}

        System.out.println("");
        //Just like the example
        int oldDimensionSize = 5;
        int newDimensionSize = 10;

        int oldNumberOfDimensions = 2;
        int newNumberOfDimensions = 5;

        int[] _2Dcoords = {2,4};
        int[] _5Dcoords = null;

        int idx = indexFromNDto1D(_2Dcoords,oldDimensionSize,oldNumberOfDimensions); //One dimension index
        System.out.println(idx);
        idx = transferFunction(idx); 
        System.out.println(idx);
        _5Dcoords = indexFrom1DToND(idx,newDimensionSize,newNumberOfDimensions); 
        System.out.println(Arrays.toString(_5Dcoords));

        System.out.println("Reversing");

        idx = indexFromNDto1D(_5Dcoords,newDimensionSize,newNumberOfDimensions);
        System.out.println(idx);
        idx = reverseTransfertFunction(idx);
        System.out.println(idx);
        _2Dcoords = indexFrom1DToND(idx,oldDimensionSize,oldNumberOfDimensions);
        System.out.println(Arrays.toString(_2Dcoords));
    }

    public static int indexFromNDto1D(int[] coords, int dimLength, int numberOfDimensions){
        //Could've use numberOfDimensions = coords.length but for symetry with the other method...
        int result = 0;

        for(int currDim = 0; currDim < numberOfDimensions; currDim++){
            int shift = (int) (Math.pow(dimLength, numberOfDimensions - currDim - 1) * coords[currDim]);
            result+= shift;
        }

        return result;
    }

    public static int[] indexFrom1DToND(int idx, int dimLength, int numberOfDimensions){
        int[] result = new int[numberOfDimensions];

        for(int currDim = 0; currDim < numberOfDimensions ; currDim++){
            int currentDimSize = (int) Math.pow(dimLength,numberOfDimensions-1-currDim);
            result[currDim] = idx / currentDimSize;
            idx = idx %  currentDimSize; 
        }

        return result;
    }

    static final int transfer = 4000;

    public static int transferFunction(int idx){
        return idx * transfer;
    }

    public static int reverseTransfertFunction(int idx){
        return idx / transfer;
}

Here's the output:

out1:233
out2:[4, 5, 2]

14
56000
[5, 6, 0, 0, 0]
Reversing
56000
14
[2, 4]
Community
  • 1
  • 1
Asoub
  • 2,273
  • 1
  • 20
  • 33
  • i have one question, how did you get from index transformation 14*4000 = 16.000.000 and how did it then turn into 16.000.000.000, i also assume [k,l,m,n,o] are the 5 dimensions with j being the size of all the dimensions together. Also im taking for example m = (j-k-l)/10*10 you mean j minus k minus l right? – Alan Liang Mar 16 '16 at 14:58
  • My bad, i miscalculated idnex transformation, I'll edit. Also, index transformation must be an injective function from [0,24] to [0, 99999] which is why i chose f(x)=x*10000/25. [k,l,m,n,o] are the coordinates of the new values. – Asoub Mar 16 '16 at 15:05
  • i thank you so much for your help its actually been so helpful, but i also wondering, two things firstly, for example the new of j = 56,000, however to get the k position, you divide by 10,000 therefore the position would be at 5.6, what would you do about this? – Alan Liang Mar 16 '16 at 15:26
  • secondly this might be really dumb but when you say m =(j-k-l)/10*10, am i correct in saying m = (j minus k minus l) div 10*10 or am i wrong? and thank you for taking so much time to explain this all to me :D – Alan Liang Mar 16 '16 at 15:28
  • oh i didnt see that it changed to modulus, oh i get the (j-k-l) part now – Alan Liang Mar 16 '16 at 15:31
  • Hope that's good now ! As for the division, you'll only get 5 out of 5.6, so you'll have 6000 left to calculate the rest of the coordinates. You can mark as solved if it's good – Asoub Mar 16 '16 at 16:01
  • thank you so much, just need some time to process everything first, if its all okay ill mark it, i cant thank you enough :D – Alan Liang Mar 16 '16 at 16:24
  • No problem ;) actually, I had some fun doing it – Asoub Mar 16 '16 at 16:25