Sei sulla pagina 1di 14

Arreglos bidimensionales en Java

Continuando con las estructuras de datos simples, en esta ocasión toca el


turno a los arreglos bidimensionales.

La dimensión.
La dimensión de un arreglo es el tamaño del arreglo, y define la forma de
organizar los datos. Un arreglo puede ser unidimensional (tener sólo una
dimensión), bidimensional (dos dimensiones) y tridimensional (tres
dimensiones). Para más sobre los arreglos unidimensionales, puedes
leer aquí.
La organización lógica de los datos en un arreglo nos permite utilizarlos de
forma muy diversa. En realidad, Java no pone restricciones en cuanto al
número de dimensiones que puede tener un arreglo, pero para los
programadores es más compleja su manipulación a mayor número de
dimensiones.

En la figura 1 te muestro los dos arreglos multidimensionales más populares:


los bidimensionales, también conocidos como matrices, y los
tridimensionales que representan lo que podríamos imaginarnos como un
cubo de datos.

Figura 1. Ejemplos de arreglos multidimensionales

Arreglos bidimensionales
Es muy común llamarles arreglos bidimensionales, arreglos 2d, o matrices,
pero en realidad, se tratan de un arreglo de arreglos. Sólo que para su
manipulación lógica, ha sido más conveniente pensar en ellos como una tabla
de valores. (De ahí que decidí hacer uso, una vez más, del trabajo fotográfico
de Carlos ZGZ para comparar la organización de un edificio de departamentos
con los datos almacenados en un arreglo bidimensional).

Declaración y construcción
La declaración de un arreglo bidimensional en Java se muestra a
continuación:

Figura 2. Declaración de un arreglo bidimensional

Como puedes observar ahora tenemos dos dimensiones: el número de


renglones y el número de filas del arreglo.

Al igual que los arreglos unidimensionales, el proceso de declaración y


construcción puede realizarse en una sola sentencia o en dos. En la figura 3
puedes ver la instrucción que crea una matriz.
Figura 3. Construcción de una matriz o arreglo bidimensional.

Al igual que los arreglos unidimensionales, las dimensiones de una matriz


deben:

▪ Ser un valor entero.


▪ Pueden expresarse como constantes numéricas (10, 100, 1000, etc)

1 arreglo = new int[10][5];


▪ También pueden expresarse como una constante simbólica, ya sea las dos
dimensiones o sólo una de ellas.

1       public static final R = 10;


2
3       public static final C = 6;
4
5       . . .
6
7       matriz = new boolean[R][C];
▪ Y también pueden usarse variables enteras previamente inicializadas.
           int renglones = 12;
1
2
           int columnas = 8;
3
4
           matriz = new
5
double[renglones][columnas];
▪ La primera dimensión se refiere al total de renglones de la matriz, y la
segunda se refiere al total de columnas.

La propiedad length.
Como ya se mencionó en la entrada sobre arreglos unidimensionales, todo
arreglo declarado y construido apropiadamente es de hecho un objeto
especial. Los objetos en Java tienen métodos y propiedades.

En el caso de un arreglo de cualquier tipo de elementos, su única propiedad


es length, la cual contiene el número de elementos en el arreglo. Pero para un
arreglo bidimensional, esta propiedad puede indicar tanto el número de
renglones como el número de columnas, dependiendo de cómo se utilice.
Observa la figura 4:

Figura 4. Uso de la propiedad length en un arrego bidimensional.

En la línea 1 se declara una matriz de enteros de 5 renglones por 3 columnas.


Luego se declara la variable x, y se le almacena el resultado de la
propiedad length. En este punto, x = 5, es decir, el número de renglones.
Después en la línea 3 se vuelve a utilizar la propiedad length, pero ahora se
establece el número de renglón en 2. En este caso, se obtiene el total de
columnas que tiene la matriz en el renglón 2.
¿Esto quiere decir que cada renglón puede alojar un número diferente de
renglones? Continúa leyendo, la cosa se pone interesante.

Tipos de matrices.
Como puedes deducir del punto anterior, existen diversos tipos de matrices:

Matrices cuadradas
Una matriz cuadrada es aquella que tiene el mismo número de renglones
como de columnas. Son las matrices que más se utilizan en el álgebra, pues
tienen ciertas propiedades que les permiten ser usadas en operaciones como
la suma de matrices. En la figura 5 puedes observar diferentes ejemplos de
matrices cuadradas.

Figura 5. Ejemplos de matrices cuadradas

Por supuesto, en este tipo de casos, matriz.lenght y matriz[i].lenght generan


el mismo resultado, por lo que se puede prescindir de utilizar la segunda
expresión.
Matrices no cuadradas
Otro tipo de matrices son las no cuadradas, y como puedes deducir, son
aquellas en donde el número de renglones no son iguales al número de
columnas. Puede darse el caso que tenga más renglones que columnas o al
revés. En la figura 6 puedes ver ejemplos de este tipo de matrices.

Figura 6. Ejemplos de matrices no cuadradas

Matrices irregulares.
Por otro lado, las matrices irregulares son aquellas donde uno o más
renglones tienen un número variable de columnas. En la figura 7 puedes ver
un ejemplo de este tipo de matrices.

Figura 7. Ejemplo de una matriz irregular.


Para la declaración y construcción de la matriz de la figura 7 se realiza lo
siguiente:

int[][] matriz = new int[4][];  // Sólo se indica el número de renglones, pero no el de


1
columnas, porque será diferente en cada renglón.
2
matriz[0] = new int[2]; // En el renglón 0, se construyen 2 columnas
3
matriz[1] = new int[3]; // El renglón 1 contiene 3 columnas
4
matriz[2] = new int[2]; // El renglón 2 contiene 2 columnas
5
matriz[3] = new int[4]; // El renglón 3 contiene 4 columnas.
Además, puedes declarar, construir e inicializar esta matriz en tiempo de
edición realizando lo siguiente:

1 int[][] matriz = { {1, 2}, {3, 4, 5}, {6, 7}, { 8, 9, 10, 11} };

Acceso a los elementos de un arreglo.


Al igual que los arreglos unidimensionales o vectores, para acceder a los
elementos de una matriz se requiere el uso de índices. Sólo que, en esta
ocasión, se deberán usar dos índices, el primero de ellos para indicar el
renglón y el segundo de ellos indicará la columna. (Casi como en un plano
cartesiano, donde x correspondería con el número de columna, y el valor y con
el número de renglón).

Una vez más, al igual que en el arreglo unidimensional, el conteo de los


índices inicia en cero, por lo que si un arreglo ha sido declarado y construido
de la siguiente forma:
1 int[][] arreglo = new int[5][4];
Tiene 20 casilas, 20 elementos, 20 espacios para almacenar datos tipo int.
Cuenta con 5 renglones o filas, pero las direcciones de renglones van desde la
0 hasta la 4. También tiene 4 columnas, pero las direcciones de columnas van
desde la 0 hasta la 3. Intentar acceder a la dirección de renglón 5, columna 4,
generará el error que se muestra en la figura 8.

Figura 8. Excepción generada al intentar acceder a una dirección fuera de los límites

Recuerda que al trabajar con arreglos bidimensionales SIEMPRE debes


especificar los dos índices: la dirección correspondiente al renglón y la
dirección de la columna. En la figura 9 puedes apreciar los errores que se
generan al olvidar los dos índices o incluso uno de ellos.
Figura 9. Error al olvidar escribir un índice en un arreglo bidimensional.

Introducción de datos a un arreglo


bidimensional.
En la figura 10 te muestro la forma general para introducir un dato a una
casilla específica de un arreglo.

Figura 10. Forma general para introducir un dato en una casilla de una matriz.

Pueden existir variaciones a esta forma general, como:

▪ El índice puede ser una constante numérica:

1 arreglo[3][2] = 9;
▪ El índice puede ser una variable tipo int:

arreglo[i][j] = 9;&nbsp; // donde <em>i</em> y <em>j</em> &nbsp;son &nbsp;variables


1
enteras e inicializadas
▪ El valor puede ser un valor que cumpla con el tipo del arreglo:

1 arreglo[2][3] = true // si arreglo es de tipo boolean


▪ El valor puede ser una variable igual al tipo del arreglo:

1 arreglo[3][2] =&nbsp; x;
▪ El valor puede ser una operación cuyo resultado sea compatible con el
tipo del arreglo:

1 arreglo[4][2] = x%y; //arreglo debe ser tipo int para poder almacenar este resultado
▪ El índice puede ser el resultado de una operación entera:

1 arreglo[i*2][j-2] = 12;

Agilizando la manipulación de los


arreglos
Cuando se requiere realizar una misma tarea sobre cada uno de los elementos
del arreglo, lo más recomendable es utilizar un ciclo para recorrer cada una de
sus casillas. En el caso de las matrices, dado que tienen dos dimensiones, se
debe utilizar dos ciclos for, uno anidado dentro del otro.

El ciclo más interno será el que más pronto se termine, en cambio el contador
del ciclo más externo sólo cambiará su valor cada vez que el ciclo interno
termine. Yo comparo los ciclos anidados con el funcionamiento de las
manecillas de un reloj analógico: la manecilla de minutos sólo puede avanzar
cuando el segundero termine de hacer su recorrido de 60. El segundero (que lo
comparo con el ciclo más interno) avanza más rápido, en tanto que el
minutero es dependiente del segundero y por lo tanto su avance es más lento.

Leyendo datos por renglones


En el siguiente ejemplo, los datos serán almacenados por renglones, eso
quiere decir que recorreremos cada una de las columnas de un renglón antes
de avanzar al siguiente. Esta forma es la más común para insertar datos en
una matriz. (El fragmento supone que se trabaja con una matriz cuadrada).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i=0; i&lt;auxiliar.length; i++){


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int j=0;
1 j&lt;auxiliar.length; j++){
2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n
3 bsp; System.out.println("Escribe el elemento:["+i+", "+j+"] del arreglo:");
4 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n
5 bsp; entrada = bufer.readLine();
6 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n
7 bsp; arreglo[i][j] = Integer.parseInt(entrada);&nbsp; &nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
Como puedes apreciar en la animación de la figura 11, el índice de cada
columna de la matriz, representado por j, es el que se mueve más rápido,
mientras el índice i que representa los renglones se mantiene estático hasta
que el recorrido por todas las columnas termine.
Figura 11. Animación del recorrido por renglones

Leyendo datos por columnas


Dependiendo de la organización de los datos, puedes necesitar leer los datos
por columnas y no por renglones. En este caso, el siguiente fragmento de
código realiza este trabajo:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i=0; i&lt;auxiliar.length; i++){


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int j=0;
1 j&lt;auxiliar.length; j++){
2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n
3 bsp; System.out.println("Escribe el elemento:["+i+", "+j+"] del arreglo: ");
4 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n
5 bsp; entrada = bufer.readLine();
6 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n
7 bsp; arreglo[j][i] = Integer.parseInt(entrada);&nbsp; &nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
En esta ocasión, como puedes apreciar en la figura 12, el índice j se mantiene
estático (se mueve más lento) y espera a que el índice i haga el recorrido por
todos los renglones de los que se compone la matriz.

Potrebbero piacerti anche