【问题标题】:Mapping a N dimension array to a M dimension array where M > N将 N 维数组映射到 M 维数组,其中 M > N
【发布时间】:2016-07-02 04:07:23
【问题描述】:

所以我想做的是将任意大小的多维数组随机折叠到更大的维度,例如:

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

将转换为:

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

我将前一个数组中的数据输入到新数组中,然后用随机数据填充新数组,这些数据是虚假数据。我的问题是创建一个访问函数,允许我从新数组中获取正确的数据,谁能给我任何指示我将如何去做?

【问题讨论】:

  • 你想如何将 25 个东西放入 10,000 个空间中?
  • @AndyTurner 以某种方式均匀分布了 25 个项目,因此更容易创建访问函数,但不仅仅是将 25 个项目放入前 25 个空格,如果这有意义吗?跨度>
  • 所以如果我理解正确的话,你想把旧数组中的数据放入一个更大的随机数据数组中,并且仍然能够恢复哪些数据是随机的,哪些来自原始数组?并且新数组的维度是随机的?
  • @Asoub 在某种意义上是的,但是,我会首先生成新数组,然后将旧数组中的数据输入到新数组中,然后按照特定顺序,随机填充数据,但是我想知道是否有一种方法可以做到这一点,所以我可以拥有一个访问功能,让我可以检索原始数据,这有意义吗?
  • 是的,我想我明白了,但它似乎真的很复杂。 M 和 N 是固定的还是动态的?正如我所看到的,一种方法是考虑两个数组都是一维数组,并使用这个一维数组从旧数组转到新数组。使用您的示例和“线性”转换, oldArray[2][3] 将是 5+5+3 :如果它是一维数组和 transformArray[2][1][3][8][ 第 13 个元素4] 会是......好吧,我现在正在努力解决这个问题。

标签: java arrays multidimensional-array split obfuscation


【解决方案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 索引,然后从这个一维索引到你的函数(“i * 4000”或任何你想要的),然后从这个新的一维索引到你的五维索引。

示例:

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

从二维到一维的位置/索引[2][4] => [14]

索引转换14*4000 => 56.000

从 1D 到 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。

对于“从 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 可能不足以包含一维索引,请小心使用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]

【讨论】:

  • 我有一个问题,你是如何从索引转换中得到 14*4000 = 16.000.000 以及它是如何变成 16.000.000.000,我也假设 [k,l,m,n, o] 是 5 个维度,j 是所有维度的总和。我也以 m = (j-k-l)/10*10 为例,你的意思是 j 减去 k 减去 l 对吗?
  • 我的错,我计算错误的 idnex 转换,我会编辑。此外,索引变换必须是从 [0,24] 到 [0, 99999] 的单射函数,这就是我选择 f(x)=x*10000/25 的原因。 [k,l,m,n,o] 是新值的坐标。
  • 我非常感谢你的帮助,它实际上很有帮助,但我也想知道,首先有两件事,例如 j = 56,000 的新,但是要获得 k 位置,你除以10,000 因此位置将是 5.6,你会怎么做?
  • 其次,这可能真的很愚蠢,但是当你说 m =(jkl)/10*10 时,我说 m = (j 减 k 减 l) div 10*10 是正确的还是我错了?感谢您花这么多时间向我解释这一切:D
  • 哦,我没看到它变成了模数,哦,我现在得到了 (j-k-l) 部分
猜你喜欢
  • 2020-05-15
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
相关资源
最近更新 更多