将N维数组映射到M维数组,其中M> 1。 ñ

时间:2016-03-16 10:27:06

标签: java arrays multidimensional-array split obfuscation

所以我试图做的是将任意大小的多维数组折叠成随机的更大尺寸,例如:

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

将转换为:

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

我将前一个数组中的数据输入到新数组中,然后使用伪造数据的随机数据填充新数组。我的问题是创建一个访问函数,它将允许我从新数组中获取正确的数据,是否有人能够给我任何关于我将如何做这个的指示?

1 个答案:

答案 0 :(得分:1)

您需要将N维数组转换为一维数组。例如,如果您使用String [][] myArray = new String[5][5]String[] oneDimArr[] = new String[5*5]myArray[0][3]将为oneDimArr[0*5+3]myArray[2][4]将为oneDimArr[2*5+4]

就像你拿走了矩阵的每一行并将它们连成一条连续的大线一样。

另一个例子:my3Darr[][][] = new String [7][7][7];和OneDimArr[] = new String[7*7*7]所以,my3Darr [4] [5] [2]将是oneDimArr [4 * 7 * 7 + 5 * 7 + 2]。

你可以在myArray和transformedArray上使用它。您将拥有一个长度为25的数组和一个长度为10000的数组。然后根据需要传输数据。例如,乘以4000(即10000/25):1D_myArray[i]将为1D_transformedArray[i*4000]。现在您只需撤消该过程:将1D_transformedArray设为transformedArray

你真的不需要在你的最终代码中为两个阵列都经过一维数组,你只需要从2D到5D索引获取方法,但是你要从2D索引到1D索引,然后从这个1D索引通过你的函数(" i * 4000"或者你想要的任何东西),然后从这个新的1D索引到你的5D索引。

例如:

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

从2D到1D [2][4] => [14]

的位置/索引

索引转换14*4000 => 56.000

从1D到5D 56.000 => [k,l,m,n,o],其中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.

对于"从1维到N维"算法我不确定,但我希望你能得到这个想法(Algorithm to convert a multi-dimensional array to a one-dimensional array可能会有其他的解释)

不确定,但您可能需要:Getting unknown number of dimensions from a multidimensional array in Java

另外注意溢出,int可能不足以包含1D索引,请注意,使用long

编辑:不得不尝试一下,所以在这里:

 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;
}

这是输出:

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

14
56000
[5, 6, 0, 0, 0]
Reversing
56000
14
[2, 4]