将数组分为子数组问题

时间:2019-05-07 11:14:34

标签: java arrays

我试图将包含许多数字的数组划分为较小的数组,为此使用2D数组。

在下面的示例中,我有一个包含16个元素(int []数字)的数组。在下面的代码中,您将看到我到目前为止所做的。当我想将其分为4个较小的数组(int arrayAmount)时,splitArray可以工作。我正在尝试将该数组分布在2D数组splittedArray上。

private static final int NUMBER_COUNT = 16;
private static int threadAmount = 4;
private static int lowestNumber = Integer.MAX_VALUE;

public static void main(String[] args) {
        int[] numbers = generateNumber(NUMBER_COUNT);
        System.out.println("Original array:\n" + Arrays.toString(numbers));
        int[][] splittedArray = new int[threadAmount][(numbers.length/threadAmount)];

        // Split arrays and print them
        splitArray(threadAmount, numbers, splittedArray);
        System.out.println("\nSplit arrays:\n" + Arrays.deepToString(splittedArray));
    }

private static void splitArray(int arrayAmount, int[] numbers, int[][] splittedArray) {
        int elPerSubArr = numbers.length / arrayAmount;

        int x = 0;
        int i = x;

        if (numbers.length != 0) {
            while (i < numbers.length) {
                for (int j = 0; j < elPerSubArr; j++) {
                    splittedArray[x][j] = numbers[i];
                    i++;
                }
                x++;
            }
        } else {
            System.out.println("There are no elements inside this array!");
        }
    }

现在,当我使用arrayAmount调用splitArray方法时,将其长度除以arrayAmount时的长度为%0可以正常工作。例如:16和4。在这种情况下,splitArray [0]至[3]将全部包含4个元素。

如何修改我的代码,使其在放置15个元素时也能正常工作?我显然在为splittedArray [x] [j]设置值的那一行上得到了ArrayIndexOutOfBoundsException,因为它总是会循环4次。我已经尝试了几个小时,无法解决。

3 个答案:

答案 0 :(得分:3)

您可以延迟int[][]分配,直到达到剩余元素为止。结果中的最后一个数组将更小。

请注意,您当前的numbers.length / arrayAmount表达式无法计算正确的长度,例如3 / 2 = 1由于整数运算。您可以使用Math.ceil()对其进行修复。

public static void main(String[] args) {
    int[] numbers = {1, 2, 3, 4, 5};
    int[][] splits = splitArray(2, numbers);
    System.out.println("Split arrays: " + Arrays.deepToString(splits));
}

private static int[][] splitArray(int splitCount, int[] numbers) {
    if (numbers.length == 0) {
        return new int[0][0];
    }

    int splitLength = (int) Math.ceil((double) numbers.length / (double) splitCount);
    int[][] splits = new int[splitCount][];

    int j = 0;
    int k = 0;
    for (int i = 0; i < numbers.length; i++) {
        if (k == splitLength) {
            k = 0;
            j++;
        }
        if (splits[j] == null) {
            int remainingNumbers = numbers.length - i;
            splits[j] = new int[Math.min(remainingNumbers, splitLength)];
        }
        splits[j][k++] = numbers[i];
    }
    return splits;
}

将打印:

Split arrays: [[1, 2, 3], [4, 5]]

答案 1 :(得分:1)

只需添加一个“ if (i<numbers.length) { ...

例如:

      for (int j = 0; j < elPerSubArr; j++) {
          if (i<numbers.length) {
                splittedArray[x][j] = numbers[i];
          } else {
                splittedArray[x][j] = 0;
          }
          i++;
      }

您对“ splittedArray”的初始化还应考虑较少的源编号:

 int rows = threadAmount;
 int cols = (int)Math.ceil((double)numbers.length / (double)threadAmount);
 int[][] splittedArray
            = new int[rows][cols];

完成课程:

package de.test.lang.stackexchange;

import java.util.Arrays;

@SuppressWarnings("UseOfSystemOutOrSystemErr")
public class SplitArray {

    private static final int NUMBER_COUNT = 15;
    private static final int threadAmount = 4;

    public static void main(String[] args) {
        int[] numbers = generateNumber(NUMBER_COUNT);
        System.out.println("Original array:\n" + Arrays.toString(numbers));
        int rows = threadAmount;
        int cols = (int) Math.ceil((double) numbers.length / (double) threadAmount);
        int[][] splittedArray = new int[rows][cols];
        // Split arrays and print them
        splitArray(numbers, splittedArray);
        System.out.println("\nSplit arrays:\n" + Arrays.deepToString(splittedArray));
    }

    private static void splitArray(int[] numbers, int[][] splittedArray) {
        int nPos = 0;
        if (numbers.length != 0) {
            for (int i = 0; i < splittedArray.length; i++) {
                for (int j = 0; j < splittedArray[i].length; j++) {
                    splittedArray[i][j] = (nPos < numbers.length) ? numbers[nPos] : 0;
                    nPos++;
                }
            }
        } else {
            System.out.println("There are no elements inside this array!");
        }
    }

    private static int[] generateNumber(int arrSize) {
        int[] x = new int[arrSize];
        for (int i = 0; i < x.length; i++) {
            x[i] = (int) (Math.random() * 1000);
        }
        return x;
    }
}

答案 2 :(得分:1)

您只需要检查长度是否超过

private static void splitArray(int arrayAmount, int[] numbers, int[][] splittedArray) {
    int elPerSubArr = numbers.length / arrayAmount;

    int x = 0;
    int i = x;
    int length = numbers.length;

    if (length != 0) {
        while (i < length) {
            for (int j = 0; j < elPerSubArr; j++) {
                if(i == length)
                     break;
                splittedArray[x][j] = numbers[i];
                i++;
            }
            x++;
        }
    } else {
        System.out.println("There are no elements inside this array!");
    }
}