繁体   English   中英

使用JAVA将大型2D数组分解为多个较小的2D数组

[英]Break large 2D array into multiple smaller 2D array using JAVA

我有一个由图像像素组成的2D数组,其大小取决于输入图像的大小。 我需要将其分成较小的9x9阵列。 为了更清楚地了解情况,我尝试说明一下这种情况:

// smallArray的行数和列数看起来像这样:它应该从imagePixels数组中复制它们,并每隔8列进行迭代,然后继续进行下8行。

    1st small   2nd small            3rd small            and so on..
    array:      array:               array: 
     012345678  91011121314151617   181920212223242526    ....
    0          0                   0
    1          1                   1
    2          2                   2
    3          3                   3
    4          4                   4
    5          5                   5
    6          6                   6
    7          7                   7
    8          8                   8

    Then move on to next 8 rows:

      012345678    91011121314151617   181920212223242526    ....
    9             9                   9
    10           10                  10
    11           11                  11
    12           12                  12
    13           13                  13
    14           14                  14
    15           15                  15
    16           16                  16
    17           17                  17

.
.
.

我已经完成了以下代码,但是无法正确执行我的逻辑。 如何停止迭代:

复制直到第9列或第9行,将其存储在数组中,在第10列/行中恢复复制,在达到9列/行后停止复制,将其存储在另一个数组中,并继续执行直到复制完imagePixels数组。

我试图将数组存储在ArrayList中,这样我可以更轻松地对所有smallArrays进行操作和进行计算。

ArrayList<double[][]> collectionofSmallArrays = new ArrayList();
double[][] imagePixels = new double[1600][1000]; //Lets say this is the size of the image
double[][] smallerArray = new double[9][9];

for(int a = 0; a<smallerArray.length; a++)
{
  for(int b =0; b<smallerArray[a].length; b++)
  { 
    for(int c=0; c<imagePixels.length; c++)
    {
      for(int d=0; d<imagePixels[c].length; d++)
      {
        smallerArray[a][b] = imagePixels[c][d];
        ...(code to stop the iteration if it reaches 9, store it in array then resume where it stops     with another new array)
        collectionofSmallArrays.add(smallerArray);
      }
    }
  }
}

任何人都可以解决该代码以达到预期的结果吗? 欣赏它。

您可能应该提供更多的上下文信息。 double精度值数组表示像素听起来像杜比奥斯。 如果使用图像,则可能会在完全不同的抽象级别上找到解决方案(我在这里考虑BufferedImage#createSubImage )。

但是,要回答这个问题:您应该将任务分解成较小的部分。 特别是,实现两种方法可能更容易:

  • 一种方法,它接收输入数组,一些坐标和一个输出数组,并将数据从输入数组的指定坐标复制到输出数组
  • 一种方法使用适当的坐标调用上述方法,以将整个数组拆分为所需大小的部分。

用伪代码:

for (each coordinates (9*r,9*c)) {
    copy the rectange (9*r,9*c)-(9*r+9,9*c+9) of the input array into an array

以下示例显示了一个非常简单的实现/测试。 请注意,可以对此进行概括和改进,但是我认为它显示了基本思想:

import java.util.ArrayList;
import java.util.List;

public class SubArrayTest
{
    public static void main(String[] args)
    {
        double inputArray[][] = createInputArray(160, 100);
        System.out.println("inputArray: "+toString(inputArray));

        List<double[][]> subArrays = createSubArrays(inputArray, 9, 9);

        for (double subArray[][] : subArrays)
        {
            System.out.println("subArray:\n"+toString(subArray));
        }
    }

    private static List<double[][]> createSubArrays(
        double inputArray[][], int subRows, int subCols)
    {
        List<double[][]> subArrays = new ArrayList<double[][]>();
        for (int r=0; r<inputArray.length; r+=subRows)
        {
            for (int c=0; c<inputArray[r].length; c+=subCols)
            {
                double subArray[][] = new double[subRows][subCols]; 
                fillSubArray(inputArray, r, c, subArray);
                subArrays.add(subArray);
            }
        }
        return subArrays;
    }

    private static void fillSubArray(
        double[][] inputArray, int r0, int c0, double subArray[][])
    {
        for (int r=0; r<subArray.length; r++)
        {
            for (int c=0; c<subArray[r].length; c++)
            {
                int ir = r0 + r;
                int ic = c0 + c;
                if (ir < inputArray.length &&
                    ic < inputArray[ir].length)
                {
                    subArray[r][c] = inputArray[ir][ic];
                }
            }
        }
    }


    //===Test methods=========================================================
    private static double[][] createInputArray(int rows, int cols)
    {
        double array[][] = new double[rows][cols]; 
        for (int r=0; r<array.length; r++)
        {
            for (int c=0; c<array[r].length; c++)
            {
                array[r][c] = r*100+c;
            }
        }
        return array;
    }

    private static String toString(double array[][])
    {
        String format = "%7.1f";
        StringBuilder sb = new StringBuilder();
        for (int r=0; r<array.length; r++)
        {
            for (int c=0; c<array[r].length; c++)
            {
                sb.append(String.format(format, array[r][c])+" ");
            }
            sb.append("\n");
        }
        return sb.toString();
    }


}

旁注:

  • 您应该始终使用其接口类型声明变量。 这意味着您不应该写

     ArrayList<String> x = new ArrayList<String>(); 

    但总是

     List<String> x = new ArrayList<String>(); 
  • 在发布的代码中,您似乎总是将相同的子数组实例添加到列表中。 这意味着最后您将在列表中有许多相同数组的实例,所有实例都具有相同的内容。 您必须在两者之间的某个位置创建一个new double[9][9]数组。

smallerArray[a][b] = imagePixels[c][d]行看起来很奇怪。 您重用相同的数组实例。 您的输出数组列表将包含对同一数组的多个引用。

  1. 您不能重用smallerArray 在for循环内创建实例,并将大小存储在常量中。
  2. 我认为以角点坐标为键的地图比存储结果的列表要好得多。
  3. 如果长度或宽度或图像不能被9整除怎么办?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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