Bienvenidos sean a este post, hoy veremos una libreria de stl.
Si vienen de los post anteriores hasta ahora hemos visto los contenedores basicos asi como estructuras de datos. El elemento que da nombre a este post es una libreria que contiene una serie de algoritmos para poder manipular la informacion contenida en estructura de datos o contenedores. Pasemos a ver algunos algoritmos que disponemos. Para ello, analizaremos el siguiente ejemplo:
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
void imprimir( std::string s ) {
std::cout << s << std::endl;
}
int main()
{
std::vector< std::string > coches = {"VW","AUDI","FORD","TOYOTA"};
for_each(coches.begin(), coches.end(), imprimir);
return 0;
}
En este ejemplo mostraremos como trabaja con la funcion for_each. Para ello primero importaremos las librerias que usaremos. string.h es para poder manejar los tipos de dato string. vector sera para poder crear un objeto de este tipo y por ulttimo, la libreria de los algoritmos. Antes del main definiremos una funcion que mostrara el valor recibido como argumento. En el main, primero crearemos un objeto de tipo vector y a este le asignaremos cuatro valores. Lo siguiente es utilizar a for_each para mostrar cada uno de los elementos. Para utilizarlo, primero debemos pasar la posicion inicial donde comenzara, por eso usamos a begin, luego la ultima posicion a procesar, por esta otra razon usamos a end, y por ultimo le pasamos la funcion que usamos en cada posicion o pasada. Esta es la que definimos anteriormente, y se encargara de devolver el valor que recibe. Compilemos y veamos como es la salida:
$ ./stl
VW
AUDI
FORD
TOYOTA
$
Realizo lo que tenia planeado hacer, mostrar la informacion contenida en el vector. Pero este codigo lo podemos mejorar un poco, para ello debemos hacer la siguiente modificacion:
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
template < class T >
class Herramienta
{
public:
void operator() ( const T & s ) {
std::cout << s << std::endl;
}
};
int main()
{
Herramienta< std::string > imprimir;
std::vector< std::string > coches = {"VW","AUDI","FORD","TOYOTA"};
for_each(coches.begin(), coches.end(), imprimir);
return 0;
}
Trabaja de la misma manera que el codigo anterior con un par de diferencias sutiles pero mas utiles. Primero, eliminamos a la funcion para usar en for_each. Y fue reemplazada por una plantilla con una clase. Esto lo haremos asi para poder manipular cualquier tipo de dato y no solamente uno establecido. Como no tenemos una funcion para aplicarla en la funcion del algoritmo, lo que haremos es una sobrecarga del operador(). Esto permitira que la clase pueda ser usada como una funcion, ya veremos como. En el main, ahora primero crearemos un objeto de la clase anterior. Y al momento de usar a for_each, pasamos el nombre del objeto creado. Como aca necesita una funcion y nosotros sobrecargamos el operador, lo tomara como tal. Si lo compilan y ejecutan deberan tener la misma salida que antes. Obviamente, este codigo es mucho mejor porque tiene mas versatibilidad con respecto al primero. Pero pasemos a ver otra funcion, para ello modifiquemos el main de la siguiente manera:
int main()
{
Herramienta< std::string > imprimir;
std::vector< std::string > coches = {"VW","AUDI","FORD","TOYOTA"};
sort(coches.begin(), coches.end());
for_each(coches.begin(), coches.end(), imprimir);
return 0;
}
En este caso, solamente agregamos una linea. Esta uttiliza a la funcion sort para ordenar al vector. Para ello, recibira el rango del vector que usaremos para ordenar. El rango es establecido mediante las funciones begin y end, para recuperar la posicion inicial y final respectivamente. Si lo compilan y ejecutan tendran la siguiente salida:
$ ./stl
AUDI
FORD
TOYOTA
VW
$
Como pueden ver, nos ordeno los valores de menor a mayor o alfabeticamente, para nuestro ejemplo. Si tuvieran que ordenarlo de manera inversa, deben usar las funciones rbegin y rend. Pasemos a ver la siguiente funcion, para ello modifiquemos el main de la siguiente manera:
int main()
{
Herramienta< std::string > imprimir;
std::vector< std::string > coches = {"VW","AUDI","FORD","TOYOTA"};
std::vector< std::string >::iterator it = std::find(
coches.begin(), coches.end(), "VW");
if (it != coches.end())
std::cout << *it << " fue encontrado\n";
else
std::cout << "No se encontro nada\n";
return 0;
}
Agregamos un nuevo objeto de tipo iterator, un condicional y eliminamos una linea. La eliminada es el for_each porque no la usaremos. El objeto nuevo es para el uso de find, esta la usaremos para buscar a la marca VW. El rango de busqueda lo establecemos mediante begin y end, pero podemos establecer el que creamos necesario. Esta funcion no devuelve un valor de ningun tipo sino que devuelve un elemento iterable. Por esta razon, para poder manejarlo debemos usar a iterator sobre el vector que creamos. El condicional verifica si el objeto anterior es distinto de la ultima posicion del vector. En caso de ser verdadero nos mostrara un mensaje de que fue encontrado. En caso contrario, nos mostrara otro para indicar lo contrario. Compilemos y veamos como es la salida:
$ ./stl
VW fue encontrado
$
Si prueban con un valor de los que no se encuentren en el vector, debera devolver el mensaje del else. Pasemos a ver una funcion mas de las disponibles en la libreria. Esta se encarga de copiar el contenido de uno a otro. Volvamos a nuestro codigo y modifiquemos nuevamente el main de la siguiente manera:
int main()
{
Herramienta< std::string > imprimir;
std::vector< std::string > coches = {"VW","AUDI","FORD","TOYOTA"};
std::vector< std::string > otros(4);
std::copy( coches.begin(), coches.end(), otros.begin());
sort(coches.begin(), coches.end());
sort(otros.rbegin(), otros.rend());
for_each(coches.begin(), coches.end(), imprimir);
std::cout << "+++++++++++++++++++++" << std::endl;
for_each(otros.begin(), otros.end(), imprimir);
return 0;
}
Primero crearemos otro vector que tendra solamente cuatro posiciones. Este sera el objeto receptor de nuestra copia. Luego usaremos a copy para realizar la copia. Primero pasaremos el rango de origen que copiaremos, y como argumento final la primera posicion desde donde comenzaremos la copia de los datos en el objeto destino. Luego haremos dos acciones para diferenciarlos, en este caso ordenar los datos en cada objeto. Para el caso de coches usaremos el orden estandar pero para otros usaremos el orden inverso, como comentamos anteriormente. Primero usaremos un for_each para mostrar el contenido del primer objeto, ponemos un separador para diferenciarlos en la salida y finalmente mostramos el contenido del objeto donde copiamos los datos. Compilemos y veamos como es la salida:
$ ./stl
AUDI
FORD
TOYOTA
VW
+++++++++++++++++++++
VW
TOYOTA
FORD
AUDI
$
Podemos ver como ahora tenemos dos objetos independientes pero con los mismos datos aunque con distintos orden. Estas son solo algunas de las funciones que podemos utilizar desde la libreria algorithm, la cual es miembro de stl. Si necesitan trabajar o conocer cuales hay disponibles, les recomiendo el siguiente link donde estan comentados y con algunos ejemplos, pero en ingles:
https://cplusplus.com/reference/algorithm/
En resumen, hoy hemos visto algorithm, que es, para que sirve, algunas de las funciones disponibles, asi como tambien algunos ejemplos para las mismas. Espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donatión
It’s for site maintenance, thanks!
$1.50
