简体   繁体   中英

Mapping a N dimension array to a M dimension array where M > N

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?

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 transformation 14*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]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM