Algoritmos 5: Arrays Vectores Matrices

En este artículo vamos a ver ARRAYS – VECTORES – MATRICES, una estructura que nos permite almacenar un conjunto de elementos.

Hasta ahora trabajamos con variables de tipos de dados simples, y con esto   podemos hacer muchísimas cosas, pero también es necesario trabajar con variables que hagan referencia a un  grupo de elementos, llamadas arreglos o arrays. Veremos sus variantes, sus beneficios  y las ventajas de operar con ellas.

Arrays

Un arreglo es una estructura que almacena un número determinado de elementos, podemos guardar una serie de números, un conjunto de palabras, etc.

Todos los elementos se identifican con el mismo nombre, el identificador único y cada elemento se diferencia por la posición en la que se encuentra dentro del array.

Generalmente debemos indicar la cantidad de elementos que va a tener al momento de crearlo.

Arrays en Algoritmos y en Programación

Desde el punto de vista de algoritmos, lo podemos ver como una cajonera. 

Es una estructura que contiene un elemento en cada cajón. A los cajones los accedemos según su posición, en nuestro caso lo distinguimos con un número de cajón.

arrays

Desde el punto de vista de la Programación, cuando declaramos un array creamos una variable que reserva todas las posiciones de memoria contiguas que necesita, una posición  por cada elemento.

Dimensiones

Como vimos en la imagen de cajoneras, hay arrays de distintas dimensiones.

Una dimensión vector

En la figura vemos el arrays más simple, el de una dimensión, conocido como vector tiene n elementos (n se usa para indicar cualquier número entero).

arrays

La posición de los elementos se identifican con los números de 0 (Primero) y el último el N-1.

Definición

Un vector se define de la forma:

tipo_dato    nombre[N]

  • el tipo de dato de cada elemento del vector
  • nombre de la variable o identificador
  • N es la cantidad de elementos por ejemplo

ENTERO numeros[3]

Todos los elementos utilizan el mismo identificador, y para acceder a uno, debemos usar el nombre de la variable y el índice tanto para asignarle valor cómo para ver su valor:

 numero[1] = 10 

IMPRIMO numeros[1]

En este caso nuestro vector tiene tres elementos 3 elementos.

ÍNDICES: 0 1 2

para acceder al primer elemento hacemos:

PRIMERO: numeros[0]

y al último:

ÚLTIMO: números[2]

Inicialización

En este caso tenemos el vector mivector: ENTERO mivector[5] de 5 elementos.

Inicializarlo consiste en cargar todas las posiciones del vector:

mivector[0]=50

mivector[1]=85

mivector[2]=32

mivector[3]=25

mivector[4]=48

Otra forma de inicializar puede ser mediante llaves, indicando cada uno de los valores:

mivector={50,85,32,25,48}

Esta forma depende del lenguaje, para nosotros es válida.

arrays

Ahora supongamos que queremos imprimir todos los valores que tiene, podemos hacer:

arrays

Pero si tengo que imprimir 100 o 1000 valores, es imposible escribir uno por uno.

Una forma de imprimir todo sería recorrerlo de a uno, de la posición 0 hasta  la posición final N-1, en secuencia.

arrays

Y aca es dónde entran las estructuras cíclicas o iterativas

PARA indice=0 A 4:

    IMPRIMO “el número” + indice + “es” + mivector[indice]

arrays

Si queremos limpiar mivector podemos inicializarlo con 0, mediante un ciclo

PARA indice=0 A 4

    mivector[indice]=0

Length

Hay una propiedad que tienen los arrays que nos indican la cantidad de elementos que tiene el vector, length:

ENTERO cantidad

cantidad= mivector.length

En el ejemplo anterior hicimos el ciclo de 0 a 4 para inicializarlo e imprimirlo.

Con esta propiedad podemos hacer:

PARA indice =0 A mivector.lenght-1

        mivector[indice]=0

y qué diferencia hay entre estas dos maneras?

Si por alguna razón, tenemos que cambiar el código, y en vez de usar un vector de cinco posiciones, necesitamos que tenga 6, 7 u 8, no tenemos que cambiar el 4 en todos lados, lo cambiamos solo en la declaración, esto no va afectar el resto del código.

No queda el 4 HARDCODEADO (datos dentro del código)

Con un bloque MIENTRAS (WHILE) también podemos recorrerlo:

ENTERO indice = 0

WHILE(indice < mivector.length)

INICIO

       IMPRIMO mivector[indice]

       indice = indice+1

FIN

Ejercicio

arrays

En este caso tenemos un vector de 10 elementos.

Lo primero que hacemos es declararlo:

ENTERO numeros[10]

Tenemos que cargarlo, vamos a usar una función a la que le pasemos el vector y lo devuelva cargado, no necesitamos que retorne nada, lo pasamos por referencia con la cláusula REF.

arrays

Al salir de la función el vector va a quedar cargado.

Vamos a calcular el promedio usando una función, le pasamos el vector y va a retornar una variable de tipo decimal, porque el promedio es una división, puede no dar un numero entero.

PEROOOOO

Recordemos que cuando se pasa una variable por valor a una función se hace una copia de la misma. Cuando es una variable simple no pasa, pero al tener un array con muchos elementos, copia toda la estructura, desperdiciando memoria. Así que este tipo de estructura conviene pasarla con la clausula REF a pesar de que no modifiquemos sus valores en el interior de la función.

arrays

Dentro de la función vamos sumando cada valor que tiene el array en la variable suma, y finalmente lo dividimos por la cantidad de elementos del vector.

Para que se entienda mejor voy a mostrar un ejemplo de cómo funciona esto:

arrays
  • Inicialmente suma vale 0.
  • Cuando arranca el ciclo y va a la primera iteración, el índice es cero, suma vale 0, más el primer elemento del vector en este caso un 3.
  • En la siguiente iteración, indice 1, a suma le va a asignar 3 más el segundo elemento del vector, en este caso un 5 así que suma va a valer 8.
  • En la tercera, indice 2, a suma le asigna 8 más el tercer elemento, un 1, así que suma va a valer 9.
  • ya no hay más elementos para recorrer, sale del ciclo, el promedio va a valer 9 dividido la cantidad de elementos, en este caso es 3, así que  la función va a retornar 3.

De la misma manera vamos a crear una función para calcular el mayor obtenerMayor… retorna un ENTERO… y recibe el vector como parámetro…

Con este mismo ejemplo vamos a pensar cómo podemos armar un algoritmo para calcular el mayor. Debemos recorrer todo el vector, vamos a usar una variable para almacenar el mayor valor, maxVal, la podría inicializar en cero.

PEROOO, si los valores del vector son negativos, entonces va a terminar siendo el mayor valor, no nos sirve.

NO LA PODEMOS INICIALIZAR EN CERO!

Así que vamos a inicializarla directamente con el primer valor del vector, con vector[0].

Analizamos la situación:

ENTERO maxVal     vector=[3,5,1]

maxVal = vector[0]   ->  maxVal =3

 vector[0] > maxVal    ->  3 > 3  ->   maxVal = 3

vector[1] > maxVal   ->  5 > 3  ->  maxVal = 5

vector[2] > maxVal   ->  1 > 5  ->  maxVal = 5

  • ¿vector[0] es mayor a maxVal? no es mayor, vale lo mismo en este caso. Así que maxVal sigue teniendo el mismo valor.
  • Vamos a la posición 1 en este caso: vector[1] vale 5 ¿es mayor que maxVal que tiene el valor 3? si, así que a maxVal le asigna 5.
  • Sigue con la siguiente posición: vector[2] no es mayor que maxVal, así que mantiene ese valor. Por lo que el valor mayor que tenemos en el vector es el 5.

Lo podemos escribir en pseudocódigo de la siguiente manera:

arrays

Recorremos el ciclo, comparamos el valor, si vector[índice] es mayor que maxVal a maxVal le asignamos vector[índice]. Una vez que termina el ciclo, retornamos maxVal, que va a contener el mayor valor.

En el programa principal creamos el vector, declaramos las variables promedio y mayor, invocamos a la función cargarVector pasando el vector como parámetro, esto va a cargar todos los datos en el vector. Invocamos a las funciones obtenerPromedio y obtenerMayor e imprimimos los resultados.

arrays

Este fue un ejemplo de vectores o arreglos unidimensionales.

De acá parten varios temas que voy a ir explicando en otros artículos, como:

  • Búsquedas
  • Ordenamiento

Son temas importantes que tienen muchos métodos de resolución.

La realidad es que al programar, hay funciones implementadas que hacen búsquedas binarias que ordenan un vector y no necesitamos saber cómo se hace, pero son temas que todo programador/a debe conocer.

Dos dimensiones matriz

Ahora vamos a hablar de arreglos de 2 dimensiones, también la podemos llamar matriz.

Visualmente la podemos ver como un tablero de ajedrez o una hoja de excel.

arrays

La posición de cada elemento está definida por dos valores, dos índices para recorrerlo uno horizontal y otro vertical (fila y columna).

arrays

El tamaño de la matriz se define por estos dos valores, la cantidad de filas y la cantidad de columnas en este caso tenemos una matriz de NxM, N filas, M columnas.

Las posiciones van a de 0 a N-1 por el lado de las filas y de 0 a M-1 por el lado de las columnas, siendo el primer elemento el de la posición [0, 0] y el ultimo el la posición [N-1, M-1].

Recorrido

Para recorrerla tenemos principalmente dos maneras por filas o por columnas. Acá vemos un recorrido por filas.

arrays

Dejamos el primer indice fijo y vamos cambiando el segundo indice: matriz[0,0], [0,1], [0,2], [0, M-1]…. Una vez terminada la fila 0 seguimos con la fila 1: matriz[1,0], [1,1], [1,2],  [1, M-1]… y así hasta la ultima fila: matriz[N-1,0], [N-,1], [N-1,2], [N-1, M-1].

¿Y Cómo se implementa esto en pseudocódigo? un solo ciclo no alcanza, necesitamos dos, uno para ir cambiando el indice de la fila y otro para ir cambiando la columna.

PARA fila = 0 a N-1

INICIO

     PARA columna = 0 a M-1

      INICIO

      IMPRIMO matriz[fila,columna]

      matriz[fila,columna] =0

      FIN

FIN

Esto hace lo que vimos antes, cuando variable fila vale cero:

PARA fila = 0 a N-1

INICIO

     PARA columna = 0 a M-1

      INICIO

      fila → 0       columna → 0,1,2,…M-1

      fila → 1       columna → 0,1,2,…M-1

La columna va cambiando de 0 a M-1, termina el ciclo de columna y el de fila incrementa la fila en 1, ahora repite el ciclo de columna de 0 a M-1 y así hasta que fila alcanza el N-1 y ejecuta el último ciclo de columna.

Otro recorrido posible es por columnas; dejando fija la columna y recorriendo la fila, en este caso:

arrays

matriz[0,0]..[1,0]..[2,0]..[N-1,0]…  matriz[0,1]..[1,1]..[2,1]..[N-1,1] y así hasta matriz[0,M-1]..[1,M-1]..[2,M-1]..[N-1,M-1]

¿cómo implementamos esto en el pseudocódigo?. En este caso tenemos el ciclo de la columna primero para dejarla fija en cada iteración

PARA columna = 0 a M-1

INICIO

    PARA fila = 0 a N-1

    INICIO

         IMPRIMO matriz[fila, columna]

N dimensiones matriz

También tenemos arrays o matrices de 3 dimensiones o más. El de 3 lo podemos ver como una tabla con profundidad, más de tres ya no podemos representarlo porque nuestra realidad es tridimensional.

arrays

Pero igual podemos trabajar con ellos aplicando lo que vimos, para acceder a un elemento necesitamos tantos indices como posiciones tenga:

N DIMENSIONES → N ÍNDICES

Por ejemplo una matriz de 3 dimensión [i,j,k] y para recorrerla en vez de un doble ciclo necesitamos un triple ciclo.

PARA i=0 a M-1

INICIO

    PARA j=0 a N-1

     INICIO

             PARA K = 0 a K-1

             INICIO

                   matriz[i,j,k]=0

Y lo mismo aplica para N dimensiones, N indices y  N ciclos para recorrerlo.

En resumen

En este capítulo vimos arrays, un tipo de variable que contiene un grupo de elementos. Hay de diferentes dimensiones: 1, 2, 3… N.

Es una herramienta súper potente, el más claro ejemplo es una hoja de excel, que probablemente sea una gran matriz de 2 dimensiones.


Pero antes, como la única manera de aprender es practicando, aca te dejo unos ejercicios para que practiques y puedas poner en práctica lo que viste:


  VARIABLES
    DECIMAL temperaturas[50]  //de 0 a 49 
    DECIMAL suma
    DECIMAL promedio
    ENTERO posicion
  
  INICIO
    // Inicializar la suma en 0
    suma = 0
  
    // Leo las 50 temperaturas
    PARA posicion = 0 A 49
    INICIO
      IMPRIMIR "Ingrese la temperatura " + (posicion+1)
      LEER temperaturas[posicion]
      suma = suma + temperaturas[posicion]
    FIN_PARA
  
    // Promedio
    promedio = suma / 50  
    IMPRIMIR "El promedio de las temperaturas es: " + promedio
  
    // Buscamos las mayores o iguales al promedio
    IMPRIMIR "Temperaturas mayores o iguales al promedio:"
    PARA posicion = 0 A 49
    INICIO
      SI (temperaturas[posicion] >= promedio) ENTONCES
        IMPRIMIR temperaturas[posicion]
    FIN_PARA  
  FIN
        

  VARIABLES
    DECIMAL estaturas[30]  // de 0 a 29
    DECIMAL suma
    DECIMAL media
    ENTERO posicion
    ENTERO masAltos
    ENTERO masBajos
  
  INICIO
    // Inicializo la suma y los contadores
    suma = 0
    masAltos = 0
    masBajos = 0
  
    // Leer las 30 estaturas
    PARA posicion = 0 A 29
    INICIO
      IMPRIMIR "Ingrese la estatura del alumno " + (posicion + 1)
      LEER estaturas[posicion]
      suma = suma + estaturas[posicion]
    FIN_PARA
  
    // Calcular la media
    media = suma / 30
    IMPRIMIR "La media de las estaturas es: " + media
  
    // Contar cuántos son más altos y cuántos más bajos que la media
    PARA posicion = 0 A 29
    INICIO
      SI (estaturas[posicion] > media) ENTONCES
        masAltos = masAltos + 1
      SINO SI (estaturas[posicion] < media) ENTONCES
        masBajos = masBajos + 1
      FIN_SI
    FIN_PARA
  
    // Imprimir los resultados
    IMPRIMIR "Cantidad de alumnos más altos que la media: " + masAltos
    IMPRIMIR "Cantidad de alumnos más bajos que la media: " + masBajos
  
  FIN
        

  //Tenemos:
  //En la posicion 1 está "BTC" (indice 0)
  //En la posicion 2 está "ETH" (indice 1)
  //En la posicion 3 está "BNB" (indice 2)
  //Debemos:
  //En la posicion 3 se va a insertar "USDT" (indice 2)
  //En la posicion 4 se va a insertar "SOL" (indice 3)
  //En la posicion 5 se va a mover "BNB" (indice 4), viene de la posicion 3 (indice 2)
  //Lo importante es entender bien los indices para cada posicion

  VARIABLES
    PALABRA criptomonedas[5]  // de 0 a 4
  
  INICIO
    // Inicializo el array con los valores ya ingresados
    criptomonedas[0] = "BTC"
    criptomonedas[1] = "ETH"
    criptomonedas[2] = "BNB"

    //Muevo BNB, esta en la posicion 3 (indice 2) y pasa a la posicion 5 (indice 4)
    criptomonedas[4] = criptomonedas[2]  // Mover BNB a la posición 5
    
    // Inserto los valores USDT y SOL en las posiciones 3 (indice 2) y 4 (indice 3)
    criptomonedas[2] = "USDT"
    criptomonedas[3] = "SOL"
  
    // Imprimir el array actualizado
    IMPRIMIR "Array de Criptomonedas actualizado:"
    PARA ENTERO i = 0 A 4
    INICIO
      IMPRIMIR "Posición " + (i+1) + ": " + criptomonedas[i]
    FIN_PARA
  
  FIN
        

  VARIABLES
    ENTERO matriz[3][3]  // Matriz de 3 filas y 3 columnas
    ENTERO sumaColumnas[3]  // Arreglo para almacenar la suma de cada columna
    ENTERO i, j
    ENTERO maxSuma, columnaMax
  
  INICIO
    // Inicializar las sumas de las columnas en 0
    PARA i = 0 A 2
      sumaColumnas[i] = 0
    FIN_PARA
  
    // Llenar la matriz con valores ingresados por el usuario
    PARA i = 0 A 2
    INICIO
      PARA j = 0 A 2
      INICIO
        IMPRIMIR "Ingrese el valor para la posición [" + i + "][" + j + "]:"
        LEER matriz[i][j]
      FIN_PARA
    FIN_PARA
  
    // Sumar las columnas - invierto los indices
    PARA j = 0 A 2
    INICIO
      PARA i = 0 A 2
      INICIO
        sumaColumnas[j] = sumaColumnas[j] + matriz[i][j]
      FIN_PARA
    FIN_PARA
  
    // Determinar la columna con la máxima suma
    //Asigno a maxSuma la columna 0
    maxSuma = sumaColumnas[0]
    columnaMax = 0
    //La columna 0 ya la asigne, no hace falta que la vuelta a recorrer
    PARA j = 1 A 2
    INICIO
      SI (sumaColumnas[j] > maxSuma) ENTONCES
        maxSuma = sumaColumnas[j]
        columnaMax = j
      FIN_SI
    FIN_PARA
  
    // Imprimir los resultados
    IMPRIMIR "Suma de las columnas:"
    PARA j = 0 A 2
    INICIO
      IMPRIMIR "Columna " + (j+1) + ": " + sumaColumnas[j]
    FIN_PARA
  
    IMPRIMIR "La columna con la máxima suma es la columna " + (columnaMax+1)
    IMPRIMIR "La suma de esa columna es: " + maxSuma
  
  FIN
        

          
  PROCEDIMIENTO llenarMatriz(REF ENTERO matriz[2][3], PALABRA nombreMatriz)
  INICIO
    ENTERO i, j
  
    IMPRIMIR "Ingrese los valores de la matriz " + nombreMatriz + ":"
    PARA i = 0 A 1
    INICIO
      PARA j = 0 A 2
      INICIO
        IMPRIMIR nombreMatriz + "[" + i + "][" + j + "]:"
        LEER matriz[i][j]
      FIN_PARA
    FIN_PARA
  FIN_PROCEDIMIENTO
  
  PROCEDIMIENTO sumarMatrices(REF ENTERO A[2][3], REF ENTERO B[2][3], REF ENTERO S[2][3])
  INICIO
    ENTERO i, j
  
    // Sumar las matrices A y B, almacenando el resultado en S
    PARA i = 0 A 1
    INICIO
      PARA j = 0 A 2
      INICIO
        S[i][j] = A[i][j] + B[i][j]
      FIN_PARA
    FIN_PARA
  FIN_PROCEDIMIENTO
  
  PROCEDIMIENTO mostrarMatriz(REF ENTERO matriz[2][3], PALABRA nombreMatriz)
  INICIO
    ENTERO i, j
  
    IMPRIMIR "La matriz " + nombreMatriz + " es:"
    PARA i = 0 A 1
    INICIO
      PARA j = 0 A 2
      INICIO
        IMPRIMIR nombreMatriz + "[" + i + "][" + j + "] = " + matriz[i][j]
      FIN_PARA
    FIN_PARA
  FIN_PROCEDIMIENTO

  // Programa principal
  VARIABLES
    ENTERO A[2][3]  // Matriz A
    ENTERO B[2][3]  // Matriz B
    ENTERO S[2][3]  // Matriz S (resultado de la suma)
  
  INICIO
    // Llenar las matrices A y B
    llenarMatriz(A, "A")
    llenarMatriz(B, "B")
  
    // Calcular la suma de las matrices
    sumarMatrices(A, B, S)
  
    // Mostrar los resultados
    mostrarMatriz(S, "Suma")
    
  FIN
        
        

En el siguiente artículo veremos registros, una herramienta que plantea encapsular datos dentro de una variable, algo que nos empieza a acercar a la programación orientada a objetos.

Recursos utilizados