Estoy tratando de dividir una matriz que contiene muchos números en conjuntos más pequeños y utilizo una matriz 2D para eso.
En el siguiente ejemplo tengo una matriz que contiene 16 elementos (int [] números). En el siguiente código se verá lo que he hecho hasta ahora. splitArray está trabajando cuando quiero dividirlo en 4 matrices más pequeñas (int arrayAmount). Estoy tratando de extender la matriz a través de una serie splittedArray 2D.
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!");
}
}
Ahora cuando llamo el método splitArray con un arrayAmount y una longitud de números que es 0% cuando se divide por el arrayAmount funciona bien. Por ejemplo: 16 y 4. splitArray [0] a [3] será todo contener 4 elementos entonces en ese caso.
¿Cómo puedo modificar mi código para que también funciona cuando pongo 15 elementos? Obviamente estoy recibiendo una ArrayIndexOutOfBoundsException
en la línea en la que establece un valor para splittedArray [x] [j] ya que siempre bucle de 4 veces. He estado tratando durante horas y no puedo entenderlo.
Puede retrasar la int[][]
asignación hasta llegar a los elementos restantes. La última matriz en el resultado será más pequeño.
Ten en cuenta que la corriente numbers.length / arrayAmount
de expresión no calculará la longitud correcta por ejemplo, 3 / 2 = 1
debido a la aritmética de enteros. Lo puede solucionar utilizando 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;
}
Imprimirá:
Split arrays: [[1, 2, 3], [4, 5]]