Fragmento de una conferencia con un mentor como parte del curso de Codegym University. Inscríbete al curso completo.


"¡Saludos, Amigo!"

"¡Hola, Rishi!"

"Ya sabes un par de cosas sobre los arreglos, e incluso te las arreglaste para resolver algunas tareas, espero. Pero no lo sabes todo. Por ejemplo, aquí hay otro hecho interesante sobre los arreglos. Los arreglos no son solo unidimensionales (lineales ) También pueden ser bidimensionales".

"Um... ¿Qué significa eso?"

"Esto significa que las celdas de la matriz pueden representar no solo una columna (o fila), sino también una tabla rectangular.

int[][]name = new int[width][height];

"Donde name es el nombre de la variable de matriz, width es el ancho de la tabla (en celdas) y height es la altura de la tabla. Eche un vistazo a un ejemplo:

int[][] data = new int[2][5];
data[1][1] = 5;
Creamos una matriz bidimensional: 2 columnas y 5 filas.
Escribimos 5 en la celda (1,1).

"Así es como se verá en la memoria:

Matrices bidimensionales

"Por cierto, para matrices bidimensionales, también puede usar la inicialización rápida:

// Lengths of months of the year in each quarter
int[][] months = { {31, 28, 31}, {30, 31, 30}, {31, 31, 30}, {31, 30, 31} };

"Hmm... eso es interesante. Si imaginamos que en el primer paréntesis interior representa un elemento, el siguiente es un segundo... ¿Entonces una matriz bidimensional es como una matriz de matrices?"

"¡Qué estudiante tan inteligente eres! Exactamente. El primer elemento es la matriz unidimensional {31, 28, 31}, el segundo es {30, 31, 30}, y así sucesivamente. Pero volveremos a eso un poco más adelante en esta lección. Hasta entonces, trata de pensar en una matriz bidimensional como una tabla con filas y columnas, formando celdas en cada intersección.

"Tengo una imagen mental de eso. Por cierto, ¿para qué se usan estas matrices bidimensionales?"

"Los programadores necesitan matrices bidimensionales con bastante frecuencia. Si observa detenidamente, casi cualquier juego de mesa se implementa utilizando una matriz bidimensional comercial: ajedrez, damas, tres en raya, batalla naval, etc.:"

batalla naval

"¡Lo entiendo! ¡El campo de juego del ajedrez o la batalla naval encaja perfectamente en matrices bidimensionales!"

"Sí, pero necesita usar números como coordenadas de celda. No 'peón e2-e4', sino 'peón (5,2) -> (5,4)'. Será aún más fácil para usted como programador. "

Organizar elementos en matrices: (x, y) o (y, x)

"La creación de arreglos bidimensionales plantea un dilema interesante. Cuando creamos un arreglo usando new int [2][5];, ¿tenemos una tabla de 'dos ​​filas y 5 columnas ' o es 'dos ​​columnas y 5 filas'?"

"En otras palabras, no está del todo claro si estamos especificando primero el ancho y luego el 'alto... o viceversa, ¿primero el alto y luego el ancho?".

"Sí, este es el dilema. Y no hay una respuesta definitiva".

"¿Qué hacer?"

"Primero, es importante comprender cómo se almacena realmente en la memoria nuestra matriz bidimensional . Naturalmente, la memoria de la computadora en realidad no tiene tablas: cada ubicación en la memoria tiene una dirección numérica secuencial: 0, 1, 2, ... Para nosotros, esta es una tabla de 2 × 5, pero en la memoria son solo 10 celdas, nada más. Sin división en filas y columnas".

"Lo entendí. Entonces, ¿cómo determinamos qué dimensión viene primero, el ancho o la altura?"

"Consideremos la primera opción. Primero el ancho, luego la altura ". El argumento a favor de este enfoque es el siguiente: todos aprenden matemáticas en la escuela y aprenden que los pares de coordenadas se escriben como 'x' (es decir, el eje horizontal) y luego 'y' (la dimensión vertical). Y esto no es solo un estándar escolar, es un estándar generalmente aceptado en matemáticas. Como dicen, no se puede discutir con las matemáticas".

"¿Es así? Bueno, si no podemos luchar contra eso, ¿entonces primero el ancho y luego el alto?"

"Hay un argumento interesante a favor de 'la altura primero, luego el ancho' . Este argumento proviene de la inicialización rápida de matrices bidimensionales. Después de todo, si queremos inicializar nuestra matriz, escribimos un código como este:"

// Matrix of important data
int[][] matrix = { {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5} };

"Entonces, ¿qué hace eso por nosotros?"

"¿Notaste algo? ¿Y si tenemos esto?

// Matrix of important data
int[][] matrix = {
  {1, 2, 3, 4, 5},
  {1, 2, 3, 4, 5}
};

"Si escribimos nuestros datos en el código línea por línea, obtenemos una tabla con 2 filas y 5 columnas".

"Ahora veo. 2 es la altura y 5 es el ancho... Entonces, ¿qué opción deberíamos usar?"

"Depende de usted decidir cuál es más conveniente. Lo más importante es que todos los programadores que trabajan en el mismo proyecto se adhieran al mismo enfoque".

"Si trabaja en un proyecto cuyo código tiene muchas matrices bidimensionales inicializadas, lo más probable es que todo se base en una inicialización rápida de datos, es decir, tendrá el estándar 'alto x ancho'.

"Si te encuentras en un proyecto que involucra muchas matemáticas y trabaja con coordenadas (por ejemplo, motores de juegos), lo más probable es que el código adopte el enfoque de 'ancho x alto'.

Cómo se organizan las matrices bidimensionales

"Ahora, ¿recuerdas la característica especial de las matrices bidimensionales que notaste al comienzo de la lección?"

"¡Sí! ¡Fue que las matrices bidimensionales son en realidad matrices de matrices!"

"Muy bien". En otras palabras, si en el caso de una matriz normal, una variable de matriz almacena una referencia a un contenedor que almacena elementos de matriz, entonces, en el caso de matrices bidimensionales, la situación estalla un poco: una matriz bidimensional La variable -array almacena una referencia a un contenedor que almacena referencias a matrices unidimensionales. Es mejor verlo en acción una vez que tratar de explicarlo cien veces:"

Cómo se organizan las matrices bidimensionales

"A la izquierda , tenemos una variable de matriz bidimensional, que almacena una referencia a un objeto de matriz bidimensional. En el medio hay un objeto de matriz bidimensional cuyas celdas almacenan matrices unidimensionales, que son las filas de una matriz bidimensional. Y a la derecha , puede ver cuatro matrices unidimensionales, las filas de nuestra matriz bidimensional. Así es como funcionan realmente las matrices bidimensionales".

"¡Fantástico! ¿Pero qué nos da?"

"Dado que un 'contenedor de contenedores' almacena referencias a 'matrices de filas', podemos intercambiar filas de manera muy rápida y sencilla. Para obtener un 'contenedor de contenedores', solo necesita especificar un índice en lugar de dos. Ejemplo:

int[][] data = new int[2][5];
int[] row1 = data[0];
int[] row2 = data[1];

"Mira el código a continuación. Podemos usarlo para intercambiar filas:"

// Matrix of important data
int[][] matrix = {
  {1, 2, 3, 4, 5},
  {5, 4, 3, 2, 1}
};

int[] tmp = matrix[0];
matrix[0] = matrix[1];
matrix[1] = tmp;
La matriz bidimensional





matrix[0]almacena una referencia a la primera fila.
Intercambiamos las referencias.

Como resultado, la matrixmatriz se ve así:
{
  {5, 4, 3, 2, 1},
  {1, 2, 3, 4, 5}
};

"Entendido. Funciona como intercambiar dos artículos ordinarios".

"Así es. Bueno, si te refieres a una celda de una matriz bidimensional, pero solo especificas un índice después del nombre de la matriz, entonces te estás refiriendo a un contenedor de contenedores cuyas celdas almacenan referencias a uno ordinario". arreglos dimensionales".

"Todo parece lógico y claro. ¡Gracias por la conferencia, Rishi!"

"De nada. Póngalo en práctica sabiamente".