当前位置: 首页 > 知识库问答 >
问题:

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

龙智
2023-03-14

我有一个由图像像素组成的2D数组,其大小取决于输入图像的大小。我需要将其分解为更小的9x9数组。为了给出更清晰的图片,我尝试说明情况:

//smallerArray的行数和列数如下:它应该从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列/第10行,之后达到第9列/第9行时停止,将其保存在另一个数组中,并继续复制,直到完成imagePixels数组的复制。

我试着把数组存储在一个数组列表中,这样对我来说,用所有更小的数组来操作和计算就更容易了。

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

任何人都可以围绕代码来实现预期的结果吗?非常感谢。

共有3个答案

邹浩
2023-03-14
    < li >您不能重复使用< code>smallerArray。在for循环中创建实例,并将大小存储在一个常数中。 < li >我认为用一些角坐标作为关键字的地图要比存储结果的列表好得多。 < li >如果图像的长度或宽度不能被9整除会怎么样?
奚高扬
2023-03-14

< code > small er array[a][b]= image pixels[c][d]线条看起来很奇怪。您重用相同的数组实例。您的输出数组列表将包含对同一数组的多个引用。

钱震博
2023-03-14

你可能应该提供更多的上下文信息。说一个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>();
    

    在发布的代码中,您似乎总是将子数组的相同实例添加到列表中。这意味着最终列表中会有相同数组的多个实例,所有实例都具有相同的内容。在两者之间的某个位置,您必须创建一个新的双[9][9]数组。

  •  类似资料:
    • 基本上,我要问的是给定一个正方形2D阵列和一个有效的补丁大小(2D子阵列的大小),我将如何做到这一点。最终,我不需要以任何方式存储子阵列,我只需要找到每个子阵列的中值并将它们存储在一个一维阵列中。中值和存储到新阵列对我来说很简单,我只是不知道如何处理原始2D阵列并正确拆分它。我已经尝试了几次,但一直出现越界错误。我有一个4x4: 我需要像这样拆分它 < code>[1,2] [3,4] [2,3]

    • 问题内容: 我想插入尺寸为4x4的2D数组“测试”(例如,实际上接近于1000x1000),其形状为8x8的网格。 我尝试使用griddata,但似乎只能使用1D吗?错误告诉我,“值和点的数量不同”,我犯错了吗? 问题答案: 您可以使用和进行此操作。 您需要确保新的X和Y范围与旧的范围相同,并且步长较小。这很容易:

    • 问题内容: 我想输出二维数组的最大值和最小值。Max可以很好地工作,但是即使在数组中没有零的情况下min也总是输出零。在本例中,我设置为99以防止较小的机会在数组中获得零。继承人完整代码: 问题答案: 由于您在中选择随机值的方式,不会存在小于零的值- 但也无法保证任何值都将恰好为零。但是,您将初始化为零,因为这是数组元素的默认值;没有什么比这更小了,所以答案总是零。 您应该在标记为“查找最小值”的

    • 问题内容: 我试图通过取元素的平均值将numpy数组分组为较小的大小。例如,将100x100阵列中的平均5x5子阵列的foreach平均值创建20x20大小的阵列。由于需要处理大量数据,这是一种有效的方法吗? 问题答案: 我已经尝试过使用较小的阵列,因此请与您的阵列进行测试: 6x6-> 3x3的示例:

    • 问题内容: 我有一个形状为(x,y)的2d数组,我想将其转换为形状为(x,y,1)的3d数组。有没有很好的Pythonic方式可以做到这一点? 问题答案: 除了其他答案,您还可以将切片与结合使用: 甚至这个(可以在任意数量的尺寸下使用):

    • 我有一个2维数组。 类似于, (0,1) (0,2) (0,3) (1,1) (1,3) (2,1) (2,2) (2,3) (2,3) (2,3) (2,3) (2,3) (2,3) (2,3) (2,3) (2,3) (2,3) (2,3) (2, 如何使用仅复制新数组中的第二个索引。 仅像, (2,1) (2,2) (2,3) 或者有没有别的办法。