Está en la página 1de 18

Tema 4

Tipos de dato estructurados: arrays

4.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

4.2 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

4.2.1 Arrays unidimensionales (vectores) . . . . . . . . . . . . . . . . . . . . . . . 121

4.2.2 Cadenas (string) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128

4.2.3 Arrays bidimensionales (matrices) . . . . . . . . . . . . . . . . . . . . . . . 132

En este capítulo se presenta una de las estructuras de datos más utilizadas en programación como
son los arrays. Dentro de este tipo de estructuras de datos se verán únicamente arrays de una
dimensión (también conocidos como vectores) y arrays de dos dimensiones (también conocidos
como matrices). Se explicará cómo declarar arrays en pseudocódigo, así como la forma en la que se
puede acceder a los elementos de un vector y de una matriz. Entre las operaciones fundamentales que
se pueden realizar con estas estructuras se explicará la asignación, la lectura/escritura de datos,
el recorrido de los elementos de un array y operaciones de actualización de elementos (añadir,
insertar y eliminar). Por último, se dedicará una sección a estudiar el tipo cadena y sus principales
operaciones, tipo que ya se introdujo brevemente en el tema anterior.

4.1 Introducción

En el primer tema de la asignatura se introdujeron brevemente los tipos de dato que generalmente
se suelen utilizar en programación para representar la información en el computador, diferenciando
entre tipos de dato simples y tipos de dato estructurados o estructuras de datos. Dentro
de los tipos estructurados podíamos diferenciar en estructuras estáticas y dinámicas, tal y como se
muestra en la Figura 4.1.
Los tipos de dato simples (también conocidos como básicos o primitivos) se caracterizan
porque no están compuestos de otras estructuras de datos, siendo el tipo entero, el tipo real y el

119
entero
real
Tipos simples caracter
logico

arrays
estáticos cadenas
registros
Tipos estructurados
listas
dinámicos árboles
grafos

Figura 4.1: Tipos de dato simples y estructuras de datos

tipo caracter los más frecuentes y utilizados por casi todos los lenguajes. Algunos lenguajes como
Python tienen integrado también el tipo logico (booleano o bool), que es considerado también en
programación un tipo de dato simple.
Los tipos de dato estructurados o estructuras de datos se construyen generalmente a
partir de los tipos simples de dato, siendo el ejemplo más representativo el tipo cadena (string).
Por tanto, se puede decir que los tipos de dato simples se pueden organizar en diferentes estructuras
de datos que, a su vez, pueden ser estáticas o dinámicas:

Las estructuras de datos estáticas son aquellas en las que el tamaño ocupado en memoria
se define antes de que el programa se ejecute (en tiempo de compilación), y dicho tamaño
no puede modificarse durante la ejecución del programa. Este tipo de estructuras están im-
plementadas en casi todos los lenguajes de programación y las principales son los arrays y
los registros. Aunque hay autores que consideran el tipo cadena como estructura de datos
estática por ser en sí un array de caracteres, existen lenguajes como Python en los que el tipo
cadena ya está implementado de forma nativa (tipo String) y no es obligatorio establecer el
tamaño ocupado en memoria para este tipo de objetos antes de utilizarlos, ya que se compor-
tan de forma dinámica en memoria. A pesar de esto, y por cuestiones de simplicidad, en esta
asignatura se considerará el tipo cadena como otro tipo más de estructura de datos estática
aparte del tipo array y el tipo registro.

Las estructuras de datos dinámicas no tienen las limitaciones o restricciones relacionadas


con establecer el tamaño de memoria ocupado en tiempo de compilación que sí presentan las
estructuras estáticas. Las estructuras dinámicas por excelencia son las listas, los árboles y
los grafos.

120
La elección del tipo de estructura de datos idónea a cada problema que queramos resolver
dependerá esencialmente del tipo de problema y, en menor medida, del lenguaje de programación
utilizado, ya que en aquellos en que no está implementada una estructura esta deberá ser simulada
con el algoritmo adecuado, dependiendo del propio algoritmo y de las características del lenguaje,
o de su fácil o difícil solución.
Por último, una característica importante que diferencia a los tipos de dato es la siguiente:
los tipos de dato simples tienen como característica común que cada variable representa a un
elemento, mientras que los tipos de dato estructurados tienen como característica común que un
identificador (nombre) puede representar múltiples datos individuales, pudiendo cada uno de estos
ser referenciado independientemente.

4.2 Arrays

Un array es una estructura de datos estática que representa una colección finita y ordenada de
elementos homogéneos, es decir, un conjunto ordenado de elementos del mismo tipo. Por lo
general todo array se identifica mediante un nombre (identificador) y una serie de índices que toman
valores enteros positivos comenzando normalmente por 0 y que permiten diferenciar la posición de
los distintos elementos que lo constituyen.
Existen diferentes tipos de array en función del número de dimensiones y de los elementos que
lo componen. Según el número de dimensiones podemos diferenciar entre arrays de una dimensión
(vectores), de dos dimensiones (matrices) o de más de dos dimensiones (arrays multidimensionales).
En algunos lenguajes como en C, a los arrays unidimensionales cuyos elementos son caracteres
se les conoce también como cadenas (string). En esta asignatura sólo se estudiarán los arrays
unidimensionales y bidimensionales.

4.2.1 Arrays unidimensionales (vectores)

Un array unidimensional se puede considerar una lista ordenada de elementos del mismo tipo.
Debido a su similitud con el concepto matemático de vector los arrays unidimensionales también
se conocen con ese nombre, es decir, como vectores. Una característica fundamental de los vectores
es que llevan asociado un único índice que designa la posición de los elementos dentro de la
lista, comenzando en 0, por lo general. En lenguajes como Python o C el primer elemento de
un array siempre tiene índice 0. Por ejemplo, la Figura 4.2 representaría gráficamente un array
unidimensional identificado con el nombre habitantes que se podría utilizar como estructura para
almacenar el número de habitantes (en unidades de millar) de 100 ciudades diferentes, donde cada
posición del array representaría una ciudad distinta.
La estructura de datos array se suele emplear normalmente en programación cuando se desea

121
Figura 4.2: Representación gráfica de un array unidimensional

almacenar un conjunto de datos que guardan cierta relación, de forma que con un único identificador
y una posición específica nos podríamos referir a cualquier dato del conjunto. Para ello los arrays
se almacenan en la memoria principal del computador en un orden adyacente de manera que, en
el ejemplo anterior, el valor numérico de la posición 1 del array habitantes (valor entero 7) estaría
almacenado en memoria en la celda siguiente a la celda donde se almacena el valor numérico de
la posición 0 del array (valor entero 30), y así sucesivamente. De este modo, cada elemento de un
vector se puede procesar como si fuese una variable simple al ocupar una posición de memoria, por
lo que para hacer referencia a cualquier elemento del array se utilizaría la siguiente sintaxis:

identificador_array [ posición ]

Por tanto, siguiendo con el ejemplo del array habitantes y teniendo en cuenta que la primera posición
del array siempre tiene índice 0, si quisiéramos asignar un nuevo valor (por ejemplo 6) a la tercera
ciudad (representada por el índice 2), se haría de la siguiente manera:

habitantes[2]← 6

La declaración de una variable de tipo array unidimensional en pseudocódigo es prácti-


camente idéntica a la que se utiliza cuando se declara una variable de tipo simple, es decir, primero
se especifica el identificador del array y después, separado por dos puntos, el tipo de los elementos
que componen el array. La única diferencia con las variables de tipo simple es que hay que indicar
el tamaño del array (número total de elementos), y esto se hace justo después del identificador y
con el tamaño (valor entero positivo) entre corchetes, tal y como se representa en el extracto del
Algoritmo 4.1.

variables
< id_array_1 > [ < tamaño_array_1 ] : < tipo_elementos_array_1 >
< id_array_2 > [ < tamaño_array_2 ] : < tipo_elementos_array_2 >
...

Algoritmo 4.1: Ejemplo de declaración de arrays unidimensionales en pseudocódigo

Por tanto, el rango de valores que puede tomar el índice de un array unidimensional será desde
0 hasta tamaño_array − 1. Para el ejemplo del array habitantes, su declaración en pseudocódigo
se haría tal y como se muestra en el Algoritmo 4.2.

122
variables
...
habitantes [100] : entero
...

Algoritmo 4.2: Declaración del array habitantes en pseudocódigo

Las operaciones típicas que se pueden realizar con arrays en programación son las siguientes:
asignación, lectura/escritura, recorrido (acceso secuencial), actualizar (insertar, eliminar), ordena-
ción y búsqueda.

4.2.1.1 Asignación, lectura y escritura de elementos

La asignación de valores a una posición de un array unidimensional se realizará en pseudocódigo


con la instrucción de asignación habitual (←) indicando la posición del elemento del array, tal y
como se ha explicado anteriormente con el ejemplo del array habitantes:

habitantes[2]← 6

En ese caso estaríamos asignando el valor entero 6 a la posición de índice 2 del array habitantes
(tercer lugar del array). Si se desea asignar valores a todos los elementos de un array se debe recurrir
por lo general a estructuras repetitivas, siendo la más habitual una estructura para. Para ello, se
utilizará la variable contador establecida en la estructura repetitiva como índice para recorrer
todas las posiciones del array. Por ejemplo, si quisiéramos inicializar todos los elementos del array
habitantes a 0 se podría hacer con una estructura iterativa para tal y como muestra el Algoritmo
4.3.

...
p a r a i ← 0 h a s t a 100 h a c e r
habitantes [ i ]← 0
fin_para
...

Algoritmo 4.3: Pseudocódigo para inicializar a 0 todos los elementos del array habitantes

En el ejemplo anterior se utiliza la variable contador i de la estructura para como índice para
recorrer todas las posiciones del array habitantes. Del mismo modo, la lectura/escritura de datos

123
en arrays u operaciones de entrada/salida normalmente se realizan con estructuras repetitivas.
Las instrucciones simples de lectura/escritura en arrays se representarán en pseudocódigo con las
mismas instrucciones leer y escribir utilizadas desde el principio de la asignatura. Así, podríamos
leer desde teclado todos los elementos del vector habitantes y después mostrarlos por pantalla tal
y como se realiza en el Algoritmo 4.4.

p a r a i ← 0 h a s t a 100 h a c e r
leer ( habitantes [ i ] )
e s c r i b i r ( habitantes [ i ] )
fin_para

Algoritmo 4.4: Pseudocódigo para leer y mostrar todos los elementos del array habitantes

4.2.1.2 Recorrido de un array unidimensional

A la operación de efectuar una acción general sobre todos los elementos de un array (por ejemplo,
leer desde teclado todos los elementos) se le denomina recorrido del vector o acceso secuencial
al vector. Lo habitual y recomendable en programación es realizar estas operaciones utilizando
estructuras repetitivas, cuyas variables de control o contador se utilizan como índice del vector (por
ejemplo, habitantes[i]). El incremento del contador del bucle producirá el tratamiento sucesivo de
los elementos del array.
Además de la estructura para (ver Algoritmo 4.4), los elementos de un array se pueden leer
también con estructuras iterativas tipo mientras o repetir. Los Algoritmos 4.5, 4.6 y 4.7 muestran
un ejemplo de cómo se podrían leer los elementos del vector habitantes con una estructura mientras
y repetir, esta última con sus dos variantes (mientras y hasta_que), respectivamente.

i←0
m i e n t r a s ( i < 100 ) h a c e r
leer ( habitantes [ i ] )
i←i+1
fin_mientras

Algoritmo 4.5: Pseudocódigo para leer los elementos del array habitantes con estructura mientras

124
i←0
repetir
leer ( habitantes [ i ] )
i←i+1
m i e n t r a s ( i < 100 )

Algoritmo 4.6: Pseudocódigo para leer los elementos del array habitantes con estructura repetir-
mientras

i←0
repetir
leer ( habitantes [ i ] )
i←i+1
hasta_que ( i = 100 )

Algoritmo 4.7: Pseudocódigo para leer los elementos del array habitantes con estructura repetir-
hasta_que

Un ejemplo típico donde se requiere hacer un recorrido secuencial de un array es cuando nos piden
calcular la media de una lista de valores. Por ejemplo, nos piden implementar un algoritmo que
calcule la media de puntos de un total de 50 puntuaciones obtenidas tras varias pruebas. Una
posible solución se muestra en la figura del Algoritmo 4.8.

a l g o r i t m o media_puntuaciones
constantes
TOTAL = 50
variables
i : entero
puntos [TOTAL] : r e a l
suma , media : r e a l

inicio
suma ← 0

125
e s c r i b i r ( "Dame l a s p u n t u a c i o n e s " )
p a r a i ← 0 h a s t a TOTAL h a c e r
l e e r ( puntos [ i ] )
suma ← suma + puntos[i]
fin_para
media ← suma/TOTAL
e s c r i b i r ( " La media e s " , media )
fin

Algoritmo 4.8: Pseudocódigo del algoritmo que calcula la media de 50 puntuaciones

4.2.1.3 Actualización de un array

La operación de actualizar un array se puede referir a dos operaciones elementales que se pueden
realizar con los elementos de dicho array:

Insertar un elemento: consiste en añadir un nuevo elemento en el array. La única condición


necesaria para realizar esta operación es comprobar que haya espacio de memoria suficiente
para el nuevo elemento, es decir, que el array no contenga todas las posiciones con las que
fue definido en su declaración ocupadas con elementos. Dicho de otro modo, para realizar
esta operación, el tamaño físico del array (el tamaño que se define en la declaración del
array) debe ser mayor que su tamaño lógico (número de elementos actuales del vector). Si
la inserción se realiza en una posición interior del array (no al final) habrá que realizar un
desplazamiento previo de los elementos que vayan a la derecha de la posición actual donde se
inserta el nuevo elemento, siempre respetando el orden de la secuencia de elementos del array.
El Algoritmo 4.9 muestra un ejemplo de inserción de un nuevo elemento en una posición
interior de un array.

algoritmo inserta_elemento_posicion_array
constantes
TAM_MAX = 5
variables
v e c t o r [TAM_MAX] : e n t e r o
tam_logico , p o s i c i o n , elem , i , temp : e n t e r o
inicio
# i n i c i a l i z a m o s e l tamaño l ó g i c o a 0

126
tam_logico ← 0
# asignamos elementos a l a s 3 primeras p o s i c i o n e s
# d e l a r r a y y a c t u a l i z a m o s e l tamaño l ó g i c o
v e c t o r [ 0 ] ← −3
vector [ 1 ] ← 2
vector [ 2 ] ← 5
tam_logico ← tam_logico + 3
# leemos l a p o s i c i ó n y e l elemento a i n s e r t a r
e s c r i b i r ( "Dame p o s i c i ó n ( e n t r e 0 y " , T AM _M AX − 1 , " ) " )
leer ( posicion )
e s c r i b i r ( "Dame e l e m e n t o a i n s e r t a r " )
l e e r ( elem )
s i ( t a m _ l o g i c o < TAM_MAX) e n t o n c e s
p a r a i ← posicion h a s t a tam_logico + 1 h a c e r
temp ← vector[i]
vector[i] ← elem
elem ← temp
fin_para
# incrementamos e l tamaño l ó g i c o en 1
tam_logico ← tam_logico + 1
fin_si
fin

Algoritmo 4.9: Ejemplo de inserción de un elemento en una posición interior de un vector

Eliminar un elemento: consiste en borrar un elemento actual del array. Al contrario que
para la inserción, el eliminar un elemento implicará un desplazamiento hacia la izquierda de
los elementos situados a la derecha del elemento eliminado para compactar el array y que
no queden huecos vacíos en el interior del mismo. Obviamente este desplazamiento no será
necesario cuando el elemento eliminado sea el de la última posición del array. El Algoritmo
4.10 muestra un ejemplo de eliminación de un elemento de una posición interior de un array.

127
algoritmo elimina_posicion_elemento_array
constantes
TAM_MAX = 5
variables
v e c t o r [TAM_MAX] : e n t e r o
tam_logico , p o s i c i o n , i : e n t e r o
inicio
# i n i c i a l i z a m o s e l tamaño l ó g i c o a 0
tam_logico ← 0
# asignamos elementos a l a s 4 primeras p o s i c i o n e s
# d e l a r r a y y a c t u a l i z a m o s e l tamaño l ó g i c o
v e c t o r [ 0 ] ← −3
vector [ 1 ] ← 2
vector [ 2 ] ← 5
vector [ 3 ] ← 9
tam_logico ← tam_logico + 4
# leemos l a p o s i c i ó n d e l elemento a e l i m i n a r
e s c r i b i r ( "Dame p o s i c i ó n ( e n t r e 0 y " , tam_logico − 1 , " ) " )
leer ( posicion )
p a r a i ← posicion h a s t a tam_logico − 1 h a c e r
vector[i] ← vector[i+1]
fin_para
# decrementamos e l tamaño l ó g i c o en 1
tam_logico ← tam_logico − 1
fin

Algoritmo 4.10: Ejemplo de eliminación de un elemento de una posición interior de un vector

4.2.2 Cadenas (string)

Una cadena de caracteres (string) es una secuencia de cero o más símbolos, que incluyen letras del
alfabeto, dígitos y caracteres especiales como el espacio en blanco. Por tanto, una cadena puede
verse como un array unidimensional cuyos elementos son de tipo carácter. La longitud de una
cadena es el número de caracteres que contiene y a la cadena que no contiene ningún carácter se le
denomina cadena vacía o nula, siendo su longitud cero. La cadena vacía no se debe confundir con

128
una cadena compuesta sólo de espacios en blanco, ya que esta tendrá como longitud el número de
blancos de la misma.
Ya se introdujo brevemente el tipo cadena en el Tema 3, indicando que en pseudocódigo se
utilizará el carácter comilla doble como delimitador del valor literal de una variable cadena. Dado
que el lenguaje de programación que vamos a emplear durante las prácticas de la asignatura tiene
implementado de forma nativa el tipo de dato cadena (str en Python), en esta asignatura se
permitirá declarar variables de tipo cadena en pseudocódigo, tal y como se muestra en el Algoritmo
4.11.

variables
...
cad1 , cad2 : cadena
...

Algoritmo 4.11: Ejemplo de declaración de variables de tipo cadena en pseudocódigo

Como se puede observar en la declaración de una variable de tipo cadena, no es necesario especificar
el número de caracteres que reservamos en memoria para la cadena, aspecto que sí es necesario
especificar cuando declaramos una variable de tipo array.
Las instrucciones básicas con cadenas son la asignación y la entrada/salida (leer/escribir). Estas
se realizan de un modo similar al tratamiento de dichas instrucciones con datos numéricos, y ya
se han explicado en temas anteriores. No obstante, existen otra serie de operaciones usuales con
cadenas que se describen a continuación:

Longitud. La longitud de una cadena es el número total de caracteres que la componen.


Por ejemplo, la cadena “Don Quijote de la Mancha” tiene 24 caracteres. Esta operación
se representa por la función len (length en inglés, que significa longitud), y su sintaxis es
len(cad), donde cad puede ser un literal de tipo cadena o una variable de tipo cadena. Por
tanto, La función len tiene como argumento una cadena, pero su resultado es un valor de tipo
entero, pudiéndose considerar un operando dentro de expresiones aritméticas:

4 + 5 + len(“prueba”) = 4 + 5 + 6 = 15

Comparación. La comparación de cadenas (igualdad y desigualdad) es una operación muy


importante, sobre todo en la ordenación o clasificación de datos de tipo caracter que se
utiliza con mucha frecuencia en aplicaciones de procesamiento de información (clasificaciones
de listas, tratamiento de textos, etc.). Los criterios de comparación se basan en el orden

129
numérico del código o juego de caracteres que admite la computadora o el propio lenguaje
de programación. En esta asignatura utilizaremos el código ASCII como código numérico de
referencia. Así, el carácter ’A’ (código ASCII 65) será menor alfabéticamente que el carácter
’C’ (código ASCII 67). En la comparación de cadenas se pueden considerar dos operaciones
elementales:

• Igualdad. Dos cadenas a y b de longitudes m y n son iguales si el número de caracteres


de a y b son los mismos (m = n), y cada carácter de a es igual al de su correspondiente
posición en b.

• Desigualdad. Los criterios para comprobar la desigualdad entre dos cadenas son utilizados
por los operadores de relación <, <=, >=, >, !=, y se ajustan a una comparación
sucesiva de caracteres correspondientes en ambas cadenas hasta comparar dos caracteres
diferentes. A partir de ese momento se resuelve la comparación según los valores ASCII
de los dos caracteres diferentes en la misma posición de ambas cadenas y no es preciso
continuar. Además, las cadenas no tienen por qué tener la misma longitud para poder
ser comparadas.

Concatenación. La concatenación es la operación de unir varias cadenas de caracteres en


una sola, pero conservando el orden de los caracteres de cada una de ellas. El símbolo que
representa la operación de concatenación varía de unos lenguajes a otros, pero en esta asig-
natura se utilizará el símbolo +. Así el resultado de la operación de concatenar las cadenas
“Juan ” y “Carlos” sería la cadena “Juan Carlos”:

Subcadena. Esta operación permite la extracción de una parte específica de una cadena, es
decir, una subcadena. La operación subcadena se representa en pseudocódigo con la siguiente
sintaxis:

subcadena (cad, inicio, fin)

donde cad es la cadena de la que debe extraerse la subcadena e inicio es un valor de tipo entero
que corresponde a la posición inicial de la subcadena. Recordemos que la posición (índice)
del primer carácter de cualquier cadena (al considerarse similar a un array) es siempre 0.
Por último, fin es un valor de tipo entero que se corresponde con la posición (índice) final
hasta la cual se extrae la subcadena (sin contar el carácter de esa posición). Por ejemplo, la
instrucción subcadena (“abcdef”, 1, 4) devolvería como resultado la cadena “bcd”.

Buscar. Una operación frecuente con cadenas es localizar si una determinada cadena forma
parte de otra cadena más grande o buscar la posición en que aparece un determinado carácter
o secuencia de caracteres en una cadena. Esta función suele ser interna en algunos lenguajes
y se define en pseudocódigo como find (encontrar en inglés), con la siguiente sintaxis:

130
find (cad, subcad)

donde cad es la cadena donde se buscará la cadena subcad. El resultado de la función es un


valor de tipo entero p que indica la posición del primer carácter donde encuentra la primera
coincidencia de subcad en cad (siempre que p >= 0). Si p == −1 es porque subcad es una
cadena vacía o no aparece en la cadena cad. Así, por ejemplo, suponiendo la variable de tipo
cadena c = “LA CAPITAL ES MADRID”, la instrucción find (c, “CAP”) retornaría un valor
3 y la instrucción find (c, “PADRID”) retornaría un valor -1.

4.2.2.1 Recorrido de una cadena

Una operación habitual con las cadenas es recorrerlas carácter a carácter para hacer cualquier
tipo de procesamiento con ellas. Al igual que se ha explicado para los arrays unidimensionales y
dado que una cadena se puede considerar un array unidimensional cuando se necesite procesarla,
lo recomendable en programación es realizar este procesamiento utilizando estructuras repetitivas,
cuyas variables de control o contador se utilizan como índice para recorrer todas las posiciones
(caracteres) de la cadena. Como ejemplo, el Algoritmo 4.12 muestra por pantalla las veces que
aparece un carácter elegido por el usuario en una cadena leída por teclado.

algoritmo cuenta_caracter_en_cadena
variables
i , total : entero
cad : cadena
car : caracter

inicio
total ← 0
e s c r i b i r ( "Dame l a cadena " )
l e e r ( cad )
e s c r i b i r ( "Dame e l c a r á c t e r a b u s c a r " )
l e e r ( car )
# p r o c e s a m o s c a r á c t e r a c a r á c t e r l a cadena
p a r a i ← 0 h a s t a len(cad) h a c e r
s i ( cad [ i ] = c a r ) e n t o n c e s
total ← total + 1
fin_si
fin_para

131
e s c r i b i r ( " El c a r á c t e r " , c a r , " a p a r e c e " , t o t a l , " v e c e s " )
fin

Algoritmo 4.12: Pseudocódigo del algoritmo que calcula las veces que aparece un carácter en una
cadena

4.2.3 Arrays bidimensionales (matrices)

La representación gráfica de un array unidimensional se corresponde con una lista de elementos


sucesivos o secuencia de datos en la que cada elemento se define o referencia por un único índice. En
cambio, existen grupos de datos que se representan mejor en forma de tabla o matriz con dos o más
índices para representar las posiciones de cada elemento. Ejemplos típicos de este tipo de grupos de
datos podrían ser: una tabla de distancias kilométricas entre ciudades, un cuadro con los horarios
de trenes o aviones, un informe de ventas periódicas (mes/unidades vendidas o bien mes/ventas
totales), etc. También se podrían definir tablas o matrices como arrays multidimensionales en las
que los elementos se referenciarían por dos, tres o más índices. Los arrays no unidimensionales se
dividen en dos grandes grupos: arrays bidimensionales (dos índices) y arrays multidimensionales
(tres o más índices). En esta asignatura se explicarán únicamente los arrays bidimensionales.
El array bidimensional (también denominado matriz o tabla) se puede considerar un vector
cuyos elementos son, a su vez, vectores. Por consiguiente, una matriz en programación es un conjunto
de elementos, todos del mismo tipo, en el que el orden de los componentes es significativo y en el que
se necesita utilizar dos índices (uno para las filas y otro para las columnas) para poder identificar
y acceder a cada elemento del array.
La representación gráfica de un array bidimensional se puede ver como un agrupamiento de
filas de elementos, tal y como se ilustra en el ejemplo de la Figura 4.3 que representa una matriz
de treinta elementos (5 x 6) con 5 filas y 6 columnas.
En una matriz se necesitan dos índices para referenciar correctamente cualquier elemento (uno
para la fila y otro para la columna). Por ejemplo, si se tiene una variable m de tipo array, la
expresión m[2][3] hace referencia al elemento situado en la tercera fila y cuarta columna ya que,
al igual que en los arrays unidimensionales, los índices de una matriz comienzan en 0. Por
ejemplo, continuando con el ejemplo del array de habitantes, la matriz mostrada en la Figura 4.4,
representa el censo de habitantes de 100 ciudades en las 3 últimas décadas, con lo que tendríamos
una matriz de 100 x 3 elementos.
Según el ejemplo de la Figura 4.4, para obtener el censo de la segunda ciudad en la primera
década se debería utilizar la expresión habitantes[1][0] y su valor de retorno sería 10, es decir, el
elemento que hay en esa posición de la tabla. Por tanto, la sintaxis que se utilizará en pseudocódigo

132
Figura 4.3: Representación gráfica de un array bidimensional

Figura 4.4: Ejemplo de representación del censo de habitantes de 100 ciudades en las 3 últimas
décadas

para acceder a los elementos de una matriz es:

id_matriz [ fila ][ columna ]

La sintaxis de la declaración de una variable de tipo array bidimensional en pseudocódigo es


similar a la que se ha explicado para los arrays unidimensionales, es decir, primero se especifica el
identificador del array y después, separado por dos puntos, el tipo de los elementos que componen
el array. La única diferencia con los arrays unidimensionales es que hay que especificar tanto el
número de filas como el número de columnas que componen la matriz (en ese orden), justo después
del identificador y cada uno entre corchetes, tal y como se representa en el extracto del Algoritmo
4.13.

variables
< id_matriz_1 > [ < f i l a s _ 1 ] [ < columnas_1 > ] : < tipo_elementos_matriz_1 >
< id_matriz_2 > [ < f i l a s _ 2 ] [ < columnas_2 > ] : < tipo_elementos_matriz_2 >

Algoritmo 4.13: Declaración de arrays bidimensionales en pseudocódigo

133
Por ejemplo, en el extracto del Algoritmo 4.14 se declaran en pseudocódigo dos matrices m1 y
m2 de dimensiones 4x5 y 3x3, siendo los elementos de m1 de tipo entero y los de m2 de tipo real.

variables
m1 [ 4 ] [ 5 ] : entero
m2 [ 3 ] [ 3 ] : real

Algoritmo 4.14: Ejemplo de declaración de arrays bidimensionales en pseudocódigo

4.2.3.1 Recorrido de un array bidimensional

Al igual que cuando tratamos con arrays unidimensionales, una de las operaciones más frecuentes
con matrices es efectuar una acción general sobre todos los elementos de la matriz (leer cada
elemento, mostrarlo por pantalla, realizar un cálculo con cada elemento de la matriz, etc.), es decir,
procesar todos los elementos de la matriz. A esta operación se le conoce como recorrido de la matriz
o acceso secuencial a la matriz.
Como se puede intuir, este tipo de operaciones se realizan utilizando estructuras repetitivas,
cuyas variables de control o contadores se utilizan para representar los dos índices de la matriz. En
este caso se necesitará un contador que represente el incremento sucesivo de las filas de la matriz
y otro que represente el incremento sucesivo de las columnas. Así, por ejemplo, la lectura de todos
los elementos de la matriz habitantes se podría realizar con dos estructuras para anidadas, tal y
como se muestra en el extracto del Algoritmo 4.15.

p a r a i ← 0 h a s t a 100 h a c e r
para j ← 0 hasta 3 hacer
leer ( habitantes [ i ] [ j ] )
fin_para
fin_para

Algoritmo 4.15: Ejemplo de recorrido por filas de la matriz habitantes para leer sus elementos

Mientras que un array unidimensional sólo admite un tipo de recorrido, en un array bidimen-
sional se puede realizar un recorrido por filas o un recorrido por columnas. En el ejemplo mostrado
en el Algoritmo 4.15 se realiza una lectura de los valores de la matriz habitantes por filas (recorrido
por filas). Para realizar una lectura de los datos por columnas (recorrido por columnas) bastaría

134
con cambiar el orden de los bucles para, de manera que el bucle más interno sería el que recorrería
las filas, y el bucle más externo recorrería las columnas, tal y como se muestra en el Algoritmo 4.16.

para j ← 0 hasta 3 hacer


p a r a i ← 0 h a s t a 100 h a c e r
leer ( habitantes [ i ] [ j ] )
fin_para
fin_para

Algoritmo 4.16: Ejemplo de recorrido por columnas de la matriz habitantes para leer sus elementos

A continuación se muestra un ejemplo típico de recorrido de una matriz. Supongamos que tene-
mos una matriz llamada notas de dimensión 40 x 10, es decir formada por 40 filas que representan
los 40 alumnos de los que queremos almacenar sus notas y 10 columnas que representan las 10
pruebas o exámenes realizados. Imaginemos que ya hemos introducido todos los valores en la ma-
triz de notas y queremos calcular la nota media de cada alumno. En ese caso se tendría que realizar
un recorrido de la matriz por filas, sumando todas las notas de cada fila y hallando su media, y así
sucesivamente con el resto de filas. El extracto del Algoritmo 4.17 muestra una posible solución al
problema planteado.

p a r a i ← 0 h a s t a 40 h a c e r
media ← 0
p a r a j ← 0 h a s t a 10 h a c e r
media ← media + notas[i][j]
fin_para
media ← media/10
e s c r i b i r ( " La media d e l alumno " , i +1 , " e s " , media )
fin_para

Algoritmo 4.17: Ejemplo de cálculo de la nota media por alumno

Observe cómo se ha utilizado la misma variable media para hacer la función de acumulador
(suma de las notas individuales) y para calcular la propia media (se podría haber utilizado otra
variable adicional suma para hacer esa función, pero no es necesario). También es importante

135
señalar el momento en el que se calcula la nota media de cada alumno: justo cuando termina de
iterar completamente el bucle más interno de la estructura repetitiva anidada, que es cuando se
ha calculado la suma de todas las notas. Otro aspecto fundamental es la inicialización a 0 de la
variable media antes de comenzar con las sumas de un nuevo alumno ya que, si no se hiciera esta
inicialización, las sumas acarrearían la media calculada del anterior alumno.
Por el contrario, si lo que se desea es calcular la nota media de cada asignatura habría que
realizar un recorrido de la matriz por columnas, sumando todos los elementos de cada columna y
hallando la media, y así sucesivamente con todas las columnas. En este caso, el bucle más externo
deberá ser el de las columnas, tal y como se muestra en el extracto del Algoritmo 4.18.

...
p a r a j ← 0 h a s t a 10 h a c e r
media ← 0
p a r a i ← 0 h a s t a 40 h a c e r
media ← media + notas[i][j]
fin_para
media ← media/40
e s c r i b i r ( " La media de l a a s i g n a t u r a " , j +1 , " e s " , media )
fin_para
...

Algoritmo 4.18: Ejemplo de cálculo de la nota media por asignatura

136

También podría gustarte