Cuando hablamos de estructuras de datos, es importante que conozcamos algunas funciones ya establecidas por librerías del mismo lenguaje de programación; en este caso enfocándonos a C++ ya que es el lenguaje que estamos usando para estos ejemplos. Estas funciones nos puedan facilitar el trabajo en la interacción con ciertas estructuras, como por ejemplo los vectores, donde veremos algunas funciones útiles para el manejo de estos. Si bien aquí no mostraremos la totalidad de funciones que puedan servirnos, al menos veremos las más comunmente usadas.
[ESTRUCTURA DE DATOS] ESTRUCTURA DE DATOS: FUNCIONES PARA VECTORES
La manipulación o manejo de estructuras de datos es importante, más aún si tenemos funciones predefinidas por el mismo lenguaje de programación que estemos usando, en tal sentido, veamos un poco de esto en el lenguaje de programación C++.
Funciones de espacio, recorrido, ordenamiento y sumatoria
Para los siguientes ejemplos, consideremos que tenemos el siguiente vector: int arr[] = { 7, 2, 9, 4, 6 };, entonces, veamos algunas funciones útiles para dicho vector.
sizeof: primero aclaremos que este primer caso no es una función, sino más bien, es un operador unario; sin embargo es muy útil en el manejo de vectores, por lo que arrancaremos por aquí. Si bien este no es exclusivo para el uso de vectores, veremos que es bastante relevante ya que sirve para capturar el espacio que ocupa un tipo de dato, dentro de la memoria, por lo tanto, a través de esto y con algunas operaciones podríamos identificar la cantidad de elementos de un vector. Por ejemplo, la siguiente fracción de código obtendrá la cantidad de elementos que fueron reservados para su almacenamiento en el vector previamente definido:
int n = sizeof(arr) / sizeof(arr[0]);
Explicando el funcionamiento del código anterior, observemos que estamos usando la función sizeof en primer lugar, pasando el parámetro arr que sería el vector; entonces, ¿qué es lo que hace este? pues, toma el vector y analiza su tipo de dato, siendo que en este caso es un entero, y, un entero ocupa 4 bytes en memoria (esto puede variar entre arquitecturas del sistema operativo o incluso entre compiladores, pero esto solo se menciona como incapié, por lo que nos enfocaremos en lo mencionado previamente), sin embargo, al ser un vector lo que se está analizando, el sizeof verifica la longitud completa de dicho vector, lo que sería un espacio reservado para 5 enteros, entonces, contabiliza esta totalidad, siendo un espacio en memoria de 4 bytes multiplicado por 5, así sería un total de 20 bytes que estaría ocupando en memoria.
Para el segundo sizeof, observemos que le pasa el vector pero especificando el primer elemento en su subíndice [0], lo que significaría que estaría pasando solo un entero de los 5 que este vector contiene, así el sizeof obtendrá 4 bytes que ocupa este dato.
Finalmente, al hacer la división de 20 bytes entre 4 bytes, estaría dando un total de 5, y ya no se menciona bytes, porque en realidad solo divida la parte numérica, obteniendo así la cantidad de elementos que podrá contener el vector. De esta manera, podemos saber en tiempo de ejecución qué cantidad de elementos fueron reservados para un vector, además, cabe mencionar que esto funciona con cualquier otro tipo de dato usado para la definción de un vector.
std::for_each: esta función pertenece a la librería algorithm, por lo tanto, será necesario importarla para usar la función en mención; dicho lo anterior, ¿qué es lo que hace esta función? pues, recorre un vector, de tal manera que suele ser más práctico que usar un for tradicional. Veamos un ejemplo:
std::for_each(arr, arr + n, [](int x){ std::cout << x << " "; });
Como se puede ver previamente, esta función posee 3 parámetros, el primero es el vector declarado el cual se recorrerá, el segundo parámetro es el vector + n donde n es la cantidad de elementos del vector y la función de este segundo parámetro es delimitar la cantidad de iteraciones, y, finalmente tenemos el tercer parámetro, esta es una función lambda (función anónima), que indica: se recorrerá cada elemento, los cuales serán cargados en la variable x, ya que tratándose de un vector de enteros, x contendrá elemento a elemento en cada iteración del bucle y dichos valores se imprimirán en pantalla de manera consecutiva (si no se entiende especialmente el tercer parámetro, se recomiendo leer qué son las funciones lambda).
std::sort: esta función es muy fácil de entender, además, como en el caso anterior, también pertenece a la librería algorithm, entonces, veamos el caso y consideremos que no se entrará en mucho detalle más que mostrar su forma de uso, dicho esto, veamos como usarlo:
std::sort(arr, arr + n);
Lo anterior, ordenará el vector en forma ascendente inplace, es decir, lo ordena y reemplaza directamente el valor dentro del array sin necesidad de asignar una respuesta de la llamada al vector; sin embargo, ¿y si queremos ordenarlo de manera descendente? pues agregamos un parámetro y ya, siendo esto de la siguiente manera:
std::sort(arr, arr + n, std::greater());
Claro que se le pasa el tipo a la función greater que indica la descendencia en el ordanemiento ya que estamos trabajando con un vector de enteros, entonces, tengamos esto muy en cuenta.
¿y existen otras maneras de ordenar con esta función? pues sí, bajo un criterio personalizado, pero eso, dejémoslo para que puedas investigarlo.
std::reverse: otra función perteneciente a la librería algorithm, y, al igual que el caso anterior, esta es una función muy sencilla de entender. Lo que hace no es más que invertir el vector, es decir, si por ejemplo tenemos los elementos 1, 2, 3 lo invierte y convierte el vector a 3, 2, 1; ¿simple cierto?, pues veamos su forma de uso:
std::reverse(arr, arr + n);
Creo que viendo lo anterior, no hay nada que explicar, entonces, pasemos a la siguiente función.
std::accumulate: esta función es de la librería numeric y lo que hace es sumar todos los elementos del vector y retornar el resultado. Su forma de uso es de la siguiente manera:
std::accumulate(arr, arr + n, 0);
Explicando los casos anteriores, quedaría claro los 2 primeros parámetros, sin embargo, ¿qué hay del tercero? pues muy simple, solo indica el valor inicial para acumular la suma de los elementos, así, retornará el resultado real de la suma acumulada de cada elemento del vector.
std::find: función de la librería algorithm y lo que hace es buscar un elemento en un vector, siempre que el tipo de dato del vector conste del operador de comparación ==, y, de encontrarlo, podemos aplicar alguna operación; además, considerar que veremos que generalmente su uso será bajo una lógica condicional, dicho esto, veamos como usarlo:
std::find(arr, arr + n, toSearch) != arr + n
Para ser breve en la explicación, etender que la expresión anterior retornará un valor booleano true si encuentra el dato buscado y false en caso de no hacerlo, además, la variable toSearch, sería aquella variable que contenga el valor que deseamos encontrar dentro del vector.
Funciones para vector de caracteres
En este caso veamos algunas funciones para un vector de caracteres, por lo tanto, consideremos que todas las funciones mencionadas seguidamente, son de la librería cstring, además, para cada ejemplo posterior, consideremos los vectores: char greet[50] = "Hola ";, char firstName[] = "Kevin Arnold"; y char otherGreet[50];.
strlen: está función solo muestra la longitud del vector pero acorde a los elementos existentes dentro de este; su uso es el siguiente:
strlen(greet);
En el caso anterior, el retorno de la función será 5, debido a que el primer vector tiene 5 caracteres, esto contando el espacio del final del texto.
strcat: esta función concatena 2 vectores de tipo char, devolviendo los valores ya concatenados en el primer parámetro del vector, es decir, en el vector greet inplace:
strcat(greet, firstName);
Entonces, de acuerdo a lo anterior, la variable greet contendría el valor "Hola Kevin Arnold".
strcpy: esta función copia el valor del vector de la derecha (segundo parámetro), al vector de la izquierda (primer parámetro) inplace:
strcpy(otherGreet, greet);
Pues simple, aquí no hay nada que explicar.
strcmp: esta función se encarga de comparar los elementos de 2 vectores de tipo char (comparación de cadenas); y, si todos los elementos son iguales entre el primer y segundo vector, la función retornará 0, caso contrario, dará un valor diferente de 0, veamos su uso:
strcmp(greet, otherGreet);
¿Simple todo esto cierto?, pues sí, efectivamente; además, debemos saber que existen muchas más funciones, pero nos detendremos aquí, ya que estas serían las funciones más comunes que podremos usar recurrentemente en el manejo de vectores en C++, claro, sin que esto sea un limitante a usar otras tantas funciones no mencioandas en este post.
CONCLUSIÓN
Debemos entender que exiten una infinidad de funciones para el manejo de vectores, más aún si usamos estructuras de datos ya definidas por el lenguaje de programación que se esté usando, además, hay muchas funciones que no fueron mencionadas en este post, pero, acorde a lo que iremos avanzando, podremos ver otras tantas funciones según la necesidad que se presente.
Finalmente, debemos entender que es importante conocer funciones predefinidas por el lenguaje de programación, para así no caer en la reinvención de la rueda, es decir, no crear funciones que pueden ya existir y solo necesitemos usarlas.
No hay comentarios:
Publicar un comentario