I am trying to divide an array containing many numbers into smaller arrays and I use a 2D array for that.
In the below example I have an array containing 16 elements (int[] numbers). In the code below you will see what I have made so far. splitArray is working when I want to divide it into 4 smaller arrays (int arrayAmount). I am trying to spread the array across a 2D array 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!");
}
}
Now when I call the splitArray method with an arrayAmount and a length of numbers that's % 0 when divided by the arrayAmount it works fine. For example: 16 and 4. splitArray[0] to [3] will all contain 4 elements then in that case.
How can I modify my code so that it also works when I put 15 elements? I am obviously getting an ArrayIndexOutOfBoundsException
on the line where I set a value for splittedArray[x][j] since it will always loop 4 times. I have been trying for hours now and can't figure it out.
You can delay the int[][]
allocation until you reach the remaining elements. The last array in the result will be smaller.
Do note that you current numbers.length / arrayAmount
expression won't calculate the correct length e.g. 3 / 2 = 1
due to integer arithmetic. You can fix it by using 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;
}
Will print:
Split arrays: [[1, 2, 3], [4, 5]]