Matrices numéricas unidimensionales

Temario:

Una matriz numérica unidimensional se puede definir como una estructura de datos que almacena una colección de elementos del mismo tipo dispuestos en una sola dimensión. También se conocen como arreglos unidimensionales.

En el contexto de C++, una matriz numérica unidimensional se declara especificando el tipo de datos de los elementos que contendrá y el tamaño de la matriz. Por ejemplo, para declarar una matriz numérica unidimensional de enteros con un tamaño de 5 elementos, puedes usar la siguiente sintaxis:

Esto crea una matriz llamada «matriz» que puede contener 6 elementos enteros (recuerda que el primer elemento de la matriz es 0). Los elementos se pueden acceder utilizando índices, comenzando desde 0 hasta el tamaño de la matriz menos 1. Por ejemplo, para acceder al primer elemento de la matriz, usarías el índice 0:

También puedes inicializar una matriz con valores específicos al momento de la declaración utilizando una lista de asignación inicial:

Además, puedes utilizar bucles como «for» para recorrer la matríz:

En resumen, las matrices numéricas unidimensionales son estructuras de datos que permiten almacenar y manipular una colección de elementos del mismo tipo dispuestos en una sola dimensión, accediendo a ellos mediante índices.

Definir una matriz

Para definir una matriz unidimensional en C++ se utiliza la sintaxis siguiente:

Donde:

tipo_de_dato.- Especifica el tipo de dato de los elementos que se almacenarán en la matriz. Puede ser cualquier tipo de dato válido en C++, como int, float, char, etc.

nombre_de_matriz.- Proporciona un nombre significativo para la matriz. Esto te permitirá acceder y manipular los elementos de la matriz.

tamaño.- Especifica el tamaño de la matriz. Debe ser un valor entero constante y mayor que cero. El tamaño determina la cantidad de elementos que la matriz puede almacenar.

Aquí hay un ejemplo de cómo definir una matriz unidimensional de enteros con un tamaño de 5 elementos:

Esto crea una matriz llamada «miMatriz«…

…que puede almacenar 6 elementos enteros. También puedes inicializar la matriz con valores específicos utilizando una lista de inicialización:

En este caso, la matriz «miMatriz» se inicializa con los valores 1, 2, 3, 4, 5.

Acceder a los elementos de una matriz

Podemos acceder a los elementos de una matriz utilizando los índices correspondientes. Aquí tienes ejemplos de cómo acceder a los elementos de una matriz unidimensional:

  • Para acceder a un elemento específico de la matriz, utiliza el nombre de la matriz seguido de los corchetes [] con el índice del elemento deseado. Por ejemplo, para acceder al tercer elemento de una matriz llamada «miMatriz«, usarimos:

Esto asignará el valor del tercer elemento de la matriz a la variable «elemento«. Recuerda que los índices comienzan desde 0, por lo que el primer elemento tiene el índice 0, el segundo elemento tiene el índice 1, y así sucesivamente.

  • Puedes utilizar los elementos de la matriz en expresiones y asignaciones. Por ejemplo, puedes realizar operaciones con los elementos de la matriz, como sumar dos elementos y asignar el resultado a otra variable:

Esto sumará el primer y segundo elemento de la matriz y asignará el resultado a la variable «suma«.

  • También puedes modificar los elementos de la matriz asignando nuevos valores a través de sus índices correspondientes:

Esto asignará el valor 10 al cuarto elemento de la matriz.

Iniciar una matriz

Veamoslo con un ejemplo:

En este ejemplo, hemos declarado una matriz llamada «matriz» con un tamaño de 3 elementos y…

…la hemos inicializado con los valores 1, 2 y 3.

Luego, utilizamos un bucle «for» para recorrer los elementos de la matriz.

La salida será:

Trabajar con matrices unidimensionales

Vamos a practicar la teoría vista hasta ahora, vamos a realizar un programa que asigne datos a una matriz unidimensional m con un número de elementos N_ELEMENTOS.

En primer lugar vamos a definir la constante N_ELEMENTOS donde fijaremos el número de elementos.

Después creamos la matriz m con el número de elementos creado anteriormente y definimos el subindice i para acceder a los elementos de la matriz.

El siguiente paso es asignar un valor desde el teclado a cada elemento de la matriz.

Una vez leida la matriz la visualizamos para comprobar el trabajo realizado.

El programa completo se muestra a continuación:

Si ejecutamos el programa nos pedirá 10 valores desde el teclado…

Una vez ingresado los valores el programa nos mostrará el título «Contenido de la matriz» y los valores de la matriz que hemos ingresado.

Tipo y tamaño de una matriz

typedef es una palabra clave utilizada para crear un alias o sinónimo de un tipo de datos existente en C++. Te permite definir un nuevo nombre para un tipo de datos existente, lo que hace que el código sea más legible y fácil de mantener. Este nuevo nombre (alias) se puede utilizar en todo el código como si fuera un tipo de datos regular. Entonces podemos declarar un sinónimo de un tipo de matriz de la siguiente manera:

La línea anterior define un nuevo tipo, t_matriz_1d, que define matrices unidimensionales de 100 elementos del tipo double. Y la siguiente sentencia utiliza este tipo para definir una matriz m:

sizeof es un operador que permite conocer el tamaño en bytes de un tipo de dato o una variable en memoria. Pues bien, cuando el operador es una matriz, el resultado es el tamaño en bytes de dicha matriz. Por ejemplo, la siguiente línea de código visualiza el número de elementos de la matriz m definida anteriormente:

O bien también podemos escribir:

Vector

Un vector es una estructura de datos dinámica que proporciona una secuencia de elementos contiguos en la memoria y permite el acceso rápido a esos elementos mediante índices. Es una implementación de una lista dinámica que se ajusta automáticamente al tamaño de los datos que contiene.

Los vectores se implementan utilizando la plantilla de la clase std::vector del contenedor de la Biblioteca Estándar de C++ (STL). Para usar vectores en tu programa, primero debes incluir la cabecera vector:

Luego, puedes crear un vector de cualquier tipo de datos especificando el tipo de dato entre los símbolos (<>). Por ejemplo, un vector de enteros se define de la siguiente manera:

El vector creado puede cambiar su tamaño de manera dinámica y automáticamente cuando se agregan o eliminan elementos. Puedes agregar elementos al final del vector utilizando el método push_back():

Para acceder a un elemento específico del vector, puedes utilizar el operador de acceso mediante índices [ ], donde el índice comienza desde cero:

También puedes obtener el tamaño del vector usando el método size():

El vector se encargará automáticamente de manejar la memoria y la reubicación de los elementos cuando sea necesario, facilitando la gestión dinámica de datos en tu programa.

Veamos un ejemplo práctico:

En este programa, utilizamos un std::vector<int> llamado «numeros» para almacenar los números enteros que el usuario ingresa a través del ciclo do-while. Luego, iteramos sobre el vector para calcular la suma y finalmente dividimos la suma entre el tamaño del vector para obtener el promedio.

Acceso a los elementos

Para acceder a un elemento podemos utilizar el operador [ ] o el método at. Con la primera manera no disponemos de verificador cuando el índice esté fuera del rango, mientras que la segunda sí.

Los métodos front/back permiten acceder al primer y último elemento de la matriz, respectivamente.

Iteradores

Los iteradores se utilizan para navegar a través de los contenedores sin necesidad de conocer el tipo utilizado para identificar los elementos. Los iteradores begin/end ofrecen los elementos en el orden normal (0, 1, 2, …, n-2, n-1); begin apunta al al primer elemento de la secuencia y end al elemento siguiente al último.

Los iteradores rbegin/rend ofrecen los elementos en el orden inverso (n-1, n-2, …, 1, 0)rbegin apunta al primer elemento de la secuencia inversa y rend al elemento siguiente al último.

Tamaño

Para conocer el tamaño de un vector hay que invocar al método size y para modificar su tamaño, al método resize; en este último caso, los elementos cpnservados desde el primero hasta el nuevo tamaño permanecen inalterados.

Para saber si un vector está vacio, utilizar el método empty. Este método devuelve true si el vector está vacio y false en caso contrario.

Eliminar elementos

El método pop_back permite eliminar el elemento del final y el método erase permite eliminar desde un elemento hasta otro.

Para eliminar todos los elementos utilizar el método clear.

Buscar elementos

El algoritmo find declarado en <algorithm> permite buscar un elemento en un contenedor; por ejemplo en un vector. Esta función devuelve un iterador al primer elemento que coincida con el valor. Por ejemplo:

Ejemplo:

Insertar elementos

El método push_back permite añadir un elemento al final y…

…el método insert permite insertar uno o más elementos en cualquier posición.

Los métodos push_back y pop_back permiten utilizar un vector como si fuera una pila (que veremos más adelante).

Matrices asociativas

En una matriz asociativa el acceso a los elementos se hace por valor en lugar de por posición (por ejemplo, una matriz que almacene díaMes que almacene el elemento de indice 1 los días del mes 1, en el índice 2 los días del mes 2 y así sucesivamente; ignoramos el elemento de índice 0).

Podemos implementar un programa de ejemplo utilizando una matriz asociativa (std::unordered_map) para contar las ocurrencias de cada letra minúscula en el texto. Aquí tienes el código:

El programa es sensible a mayúsculas y minúsculas. Si deseas ignorar las mayúsculas y contar solo las minúsculas, puedes convertir todas las letras del texto a minúsculas antes de contar las ocurrencias, utilizando la función std::tolower de la biblioteca <cctype>.

Map

Facilita la creación y manipulación de matrices asociativas. Veamos un programa de ejemplo:

En este ejemplo, hemos reemplazado std::unordered_map por std::map. La diferencia principal es que std::map mantiene las claves ordenadas, lo que significa que los resultados se mostrarán en orden alfabético, mientras que std::unordered_map no garantiza ningún orden.

La lógica del programa es la misma que en los ejemplos anteriores. Contamos las ocurrencias de cada letra en el texto utilizando el bucle for, y almacenamos las frecuencias en la matriz asociativa frecuencias. Luego, iteramos sobre frecuencias y mostramos el resultado, que estará ordenado alfabéticamente debido a la naturaleza ordenada de std::map.

Este programa también es sensible a mayúsculas y minúsculas. Si deseas ignorar las mayúsculas y contar solo las minúsculas, puedes convertir todas las letras del texto a minúsculas antes de contar las ocurrencias, utilizando la función std::tolower de la biblioteca <cctype>, como se mencionó en los ejemplos anteriores.