Está en la página 1de 16

Algoritmo Genérico.

Los algoritmos son la base de la computación. Ser capaz de escribir un


algoritmo que funcione con cualquier tipo de se secuencia hace que sus
programas sean simples y seguros. La habilidad para adaptar algoritmos en
tiempo de ejecución ha revolucionado el desarrollo de software.
Pensemos en esto como si tenemos una pelota y que nos sirve, para jugar
Futbol, basquetbol o voleibol.
El subconjunto de la Librería Estándar de C++ conocido como Standard
Template Library (STL) fue diseñado entorno a algoritmos genéricos, código
que procesa secuencias de cualquier tipo de valores de un modo seguro. El
objetivo era usar algoritmos predefinidos para casi cualquier tarea, en lugar de
codificar a mano cada vez que se necesitara procesar una colección de datos.
La Standard Template Library (STL) es una colección de estructuras de datos
genéricas y algoritmos escritos en C++. STL no es la primera de tales librerías,
así la mayor parte de los compiladores de C++ disponen (o disponían) de
librerías similares y, también, están disponibles varias librerías comerciales.
Uno de los problemas de estas librerías es que son mutuamente
incompatibles, lo que obliga a los programadores a aprender nuevas librerías
y a migrar de un proyecto a otro y de uno a otro compilador. Sin embargo, STL
ha sido adoptado por el comité ANSI de estandarización del C++, lo que
significa que está soportado como una extensión más del lenguaje por todos
los compiladores.
El diseño de la Standard Template Library es el resultado de varios años de
investigación dirigidos por Alexander Stepanov y Meng Lee de Hewlett-
Packard, y David Musser del Rensselaer Polytechnic Institute. Su desarrollo se
inspiró en otras librerías orientadas a objetos y en la experiencia de sus
creadores en lenguajes de programación imperativos y funcionales, tales como
Ada y Scheme.
La STL proporciona una colección de estructuras de datos contenedoras y
algoritmos genéricos que se pueden utilizar con éstas. Una estructura de datos
se dice que es contenedora si puede contener instancias de otras estructuras
de datos.

STL
La Biblioteca de plantillas estándar (STL) es un conjunto de clases de plantillas
de C ++ para proporcionar estructuras y funciones de datos de programación
comunes, como listas, pilas, matrices, etc. Es una biblioteca de clases de
contenedores, algoritmos e iteradores. Es una biblioteca generalizada y por
lo tanto, sus componentes están parametrizados. Un conocimiento práctico
de las clases de plantillas es un requisito previo para trabajar con STL.

STL tiene cuatro componentes

• Algoritmos
• Contenedores
• Funciones
• Iteradores

Algoritmos

El algoritmo de encabezado define una colección de funciones especialmente


diseñadas para ser utilizadas en rangos de elementos. Actúan en los
contenedores y proporcionan medios para diversas operaciones para el
contenido de los contenedores.

Funciones

El STL incluye clases que sobrecargan la función de operador de llamada. Las


instancias de tales clases se denominan objetos de función o functores. Los
funcionalizadores permiten personalizar el funcionamiento de la función
asociada con la ayuda de los parámetros que se deben pasar.
Iteradores

Como su nombre indica, los iteradores se utilizan para trabajar en una


secuencia de valores. Son la principal característica que permiten generalidad
en STL.

Contenedores

Los contenedores o clases de contenedores almacenan objetos y datos. Hay


un total de siete clases estándar de "primera clase" de contenedores y tres
clases de adaptadores de contenedores y solo siete archivos de encabezado
que proporcionan acceso a estos contenedores o adaptadores de
contenedores.

Funciones comunes de los contenedores

Funciones Descripción
miembros comunes
constructor Un constructor para crear un contenedor vacío. Por lo general,
predeterminado cada contenedor cuenta con varios constructores que
proporcionan distintos métodos de inicialización.
constructor de Un constructor que inicializa al contenedor para que sea una
copia copia de un contenedor existente del mismo tipo.
destructor La función destructora para encargarse de la limpieza, una vez
que el contenedor ya no sea necesario.
empty Devuelve true si no hay elementos en el contenedor, en caso
contrario devuelve false.
insert Inserta un elemento en el contenedor.
size Devuelve el número de elementos que hay actualmente en el
contenedor.
operator= Asigna un contenedor a otro.
operator< Devuelve true si el primer contenedor es menor que el segundo,
en caso contrario devuelve false.
operator<= Devuelve true si el primer contenedor es menor o igual que el
segundo, en caso contrario devuelve false.
operator> Devuelve true si el primer contenedor es mayor que el segundo,
en caso contrario devuelve false.
operator>= Devuelve true si el primer contenedor es mayor o igual que el
segundo, en caso contrario devuelve false.
operator== Devuelve true si el primer contenedor es igual que el segundo, en
caso contrario devuelve false.
operator!= Devuelve true si el primer contenedor es distinto que el segundo,
en caso contrario devuelve false.
swap Intercambia los elementos de dos contenedores.
Funciones que solo se enecuentran en contenedores de primera clase
max_size Devuelve el número máximo de elementos para un contenedor.
begin Las dos versiones de esta función devuelven ya sea un iterator o
un const_iterator que hace referencia al primer elemento del
contenedor.
end Las dos versiones de esta función devuelven ya sea un iterator o
un const_iterator que hace referencia a la siguiente posición
después del final del contenedor.
rbegin Las dos versiones de esta función devuelven ya sea un
reverse_iterator o un const_revese_iterator que hace referencia
al último elemento del contenedor.
rend Las dos versiones de esta función devuelven ya sea un
reverse_iterator o un const_revese_iterator que hace referencia
a la posición que está antes del primer elemento del contenedor.
erase Elimina uno o más elementos del contenedor.
clear Elimina todos los elementos del contenedor.

• Contenedores de secuencia: implementa estructuras de datos a las que


se puede acceder de forma secuencial, organizan los datos en orden
lineal: primer elemento, segundo, .. .
o vector
o lista
o deque
• Adaptadores de contenedores: proporcionan una interfaz diferente
para contenedores secuenciales.
o queue
o priority_queue
o stack
• Contenedores asociativos: implementa estructuras de datos ordenadas
que se pueden buscar rápidamente (complejidad O (log n) ) almacena
objetos de forma ordenada basándose en una llave.
o set
o Multiset
o mapa
o multimapa
Contenedores de secuencia
Vector

Generalización de un vector o array que


almacena una colección de elementos del
mismo tipo. Los elementos se acceden de
manera directa por medio de un índice, en el
rango de 0 a n-1, siendo n el tamaño del
vector. Dicho tamaño puede aumentarse o
decrementarse según las necesidades de
manera dinámica.

La forma de declarar un
vector es muy parecida a
declarar un tipo de dato
vector<string> sentence;

// Se reserva espacio para 5 elementos para

// evitar que se tenga que resituar la memoria.

sentence.reserve(5);
solo que hay que indicar el tipo de dato
sentence.push_back("Hello,");
a almacenar, vector<tipo_de_dato>
nombre_del_vector, ejemplo: sentence.push_back("how");

sentence.push_back("are");
vector<int> vectorEnteros; sentence.push_back("you");

sentence.push_back("?");
vector<String> vectorCadenas;
cout<< "max_size(): "<< sentence.max_size()<< endl;
vector<MiTipo> vectorMiTipo; cout<< "size(): "<< sentence.size() << endl;

cout<< "capacity(): "<< sentence.capacity()<< endl;


vector<queue<double>> vectorDeColas;
// Intercambio de elementos.

swap (sentence[1], sentence[3]);

// Inserción de "always" antes de "?"

sentence.insert(find(sentence.begin(),sentence.end(),"?"),
"always");

// Se asigna "!" al último elemento.

sentence.back() = "!";
Lista

Las listas son contenedores de secuencia que permiten la asignación de


memoria no contigua. En comparación con vector, la lista tiene un recorrido
lento, pero una vez que se ha encontrado una posición, la inserción y la
eliminación son rápidas. Normalmente, cuando decimos una lista, hablamos
de una lista doblemente enlazada. Para implementar una lista enlazada
individualmente, usamos la lista hacia adelante.

Tabla de métodos: clase list


assign asigna elementos a la lista
back devuelve una referencia a el último componente de la lista
begin devuelve un iterator al principio de la lista
clear elimina todos los componentes de la lista
empty true si la lista está vacía
end devuelve un iterator al final de la lista
erase elimina componentes de la lista
front devuelve una referencia al primer componente de la lista
insert inserta componentes en la lista
max_size devuelve el número máximo de elementos soportados por la lista

merge une dos listas


pop_back elimina el último componente de la lista
pop_front elimina el primer componente de la lista
push_back añade un componente al final de la lista
push_front añade un componente al frente de la lista
rbegin devuelve un reverse_iterator hacia el final de la lista
remove elimina componentes de la lista
remove_if elimina condicionalmente componentes de la lista
rend devuelve un reverse_iterator hacia el inicio de la lista
resize cambia el tamaño de la lista
reverse pone al revés los componentes de la lista
size devuelve el número de componentes en la lista
sort ordena la lista
splice unión de dos listas
swap intercambia el contenido de una lista con el de otra
unique elimina componentes duplicados

// Un simple ejemplo de uso de la plantilla de clase list


#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <list>

using namespace std;

int main(int argc, char *argv[])


{
list<double> lalista;//Instanciamos la clase list
double num, suma=0;

cout << "Una sencilla calculadora" << endl;

do
{
cout << "Ingrese un número, 0 para salir: ";
cin >> num;
if (num != 0) lalista.push_back(num);
}
while (num != 0);

cout << "----------" << endl;

while( !lalista.empty() )
{
num = lalista.front();
cout << setw(10) << num << endl;
suma += num;
lalista.pop_front();
}
cout << "----------" << endl;

cout << setw(10) << suma << endl;

system("PAUSE");
return EXIT_SUCCESS;
}
Representación grafica Deque

Deque
Un deque se define de forma recursiva:
internamente mantiene una cola de dos
extremos de trozos de tamaño fijo. Cada
fragmento es un vector, y la cola ("mapa" en el
gráfico a continuación) de los trozos en sí es
también un vector.
Deque se implementa normalmente como un
vector de vectores (una lista de vectores no
puede dar acceso aleatorio de tiempo
constante). Si bien el tamaño de los vectores
secundarios depende de la implementación, un
algoritmo común es usar un tamaño constante
en bytes.

int main(int argc, char *argv[])


{
deque<char> v;
char x;

// Metemos en la cola v valores desde la 'A'


hasta la 'Z'
// mediante el método push_back.
for (x = 'A'; x <= 'Z'; x++) v.push_back(x);

// Metemos en la cola v valores desde la '0'


hasta la '9'
// mediante el método push_front.
for (x = 0; x <= 9; x++) v.push_front(x);

// despliegue de los elementos de la cola


// mediante el operador [].
for(int i = 0; i < v.size(); i++)
cout << v[i] << " ";

// despliegue de los elementos del vector v


// mediante el método at().
for(int i = 0; i < v.size(); i++)
cout << v.at(i) << " ";

cout << endl;

cin.get();
}
Deque(Cola )
Contenedor, representado como una sucesión de objetos que limita la forma
en que éstos se añaden a ella, al igual la manera de abandonarla.
Así, una cola sólo permite introducir objetos por un extremo de la sucesión,
final, y la recuperación por el opuesto, frente. Los elementos se ubican en
estricto orden de llegada. (Secuencia FIFO).

Tabla de métodos: clase queue


Nombre Descripción queue priority_queue
empty cierto (true) si la cola está vacia Si Si
pop borra el elemento del frente de la cola Si Si
push agrega un elemento al frente de la cola Si Si
size regresa el número de elementos en la cola Si Si
front regresa una referencia al primer elemento en la Si No
cola
back regresa una referencia al último elemento en la Si No
cola
top regresa una referencia al primer elemento en la No Si
cola
// CPP code to illustrate
// Queue in Standard Template Library (STL)
#include <iostream>
#include <queue>

using namespace std;

showq(queue < int > gq)


{
queue < int > g = gq;
while (!g.empty())
{
cout << '\t' << g.front();
g.pop();
}
cout << '\n' ;
}

int main()
{
queue < int > gquiz;
gquiz.push(10);
gquiz.push(20);
gquiz.push(30);

cout << "The queue gquiz is : " ;


showq(gquiz);

cout << "\ngquiz.size() : " <<


gquiz.size();
cout << "\ngquiz.front() : " <<
gquiz.front();
cout << "\ngquiz.back() : " <<
gquiz.back();

cout << "\ngquiz.pop() : " ;


gquiz.pop();
showq(gquiz);

return 0;
}
Prioridad_queue

Las colas de prioridad son un tipo de


adaptadores de contenedor, diseñados
específicamente de tal manera que el
primer elemento de la cola es el más
grande de todos los elementos de la cola
y los elementos están en orden no
decreciente (por lo tanto, podemos ver
que cada elemento de la cola tiene una
prioridad {orden fijo}).

Trabajar con un valor de priority_queue


es similar a administrar un montón en un
contenedor de acceso aleatorio, con la ventaja de no poder invalidar
accidentalmente el montón.

#include <queue>
Otro ejemplo, imaginemos #include <list>

que tenemos un barco: using namespace std;

class Barco {
La función subirPasajero() public:
void subirPasajero(const Pasajero& pasajero);
debe agregar un pasajero void abandonarBarco(list<Pasajero>& pasajerosEnOrden);

al barco, y private:
priority_queue<Pasajero> pasajeros_;
abandonarBarco() debe };
sacar todos los pasajeros
void Barco::subirPasajero(const Pasajero& pasajero)
del barco y colocarlos (por {
pasajeros_.push(pasajero);
orden de prioridad) en la }
lista que se recibe como
void Barco::abandonarBarco(list<Pasajero>& pasajerosEnOrden)
argumento. {
while (!pasajeros_.empty()) {
pasajerosEnOrden.push_back(pasajeros_.top());
pasajeros_.pop();
}
}
Stack (Pila)

Las pilas son un tipo de adaptadores de contenedor con el tipo de trabajo LIFO
(último en entrar, primero en salir), donde se agrega un nuevo elemento en
un extremo y (arriba) un elemento se elimina solo de ese extremo.

El uso de estructuras de
pila a travez de la plantilla
de clase stack, la cual posee
el mecanismo de operación
necesario para manejar
operaciones de insertar
(push), borrar(pop), entre
otras. La clase stack posee

// programa: pila01.cpp

// un simple ejemplo del uso de la


únicamente cinco métodos y dos constructores. plantilla stack

#include <cstdlib>
En seguida se presenta un ejemplo sumamente #include <iostream>
básico, el cual consiste en crear una pila para #include <stack>
contener elementos de tipo char. Los caracteres se using namespace std;
introducen en orden desde la 'A' hasta la 'Z' y, tal
int main(int argc, char *argv[])
como tiene que ser, al recuperarlos se obtienen en
{
orden inverso, o sea, desde la 'Z' hasta la 'A'.
stack<char> s;

La plantilla de clase actúa como un contenedor para for (int i='A'; i <= 'Z'; i++)

el contenedor subyacente, solo se proporciona un s.push(i);

conjunto específico de funciones. La pila empuja y while (! s.empty() )


hace estallar el elemento desde la parte posterior {
del contenedor subyacente, conocido como la parte cout << s.top() << " " ;
superior de la pila. s.pop();
Nombre Descripción }
empty cierto (true) si el stack está vacio
cout << endl;
pop borra el elemento en el tope del stack
system("PAUSE");
push agrega un elemento en el tope
return EXIT_SUCCESS;
size regresa el numero de elementos
}
top regresa el último elemento
Set (Conjunto)

Los conjuntos son un tipo de


contenedores asociativos en los
que cada elemento debe ser
único, porque el valor del
elemento lo identifica. El valor
del elemento no se puede
modificar una vez que se agrega
al conjunto, aunque es posible
eliminar y agregar el valor
modificado de ese elemento.

La clasificación se realiza
mediante la tecla de función de comparación compara. Las operaciones de
búsqueda, extracción e inserción tienen complejidad logarítmica. Los
conjuntos se implementan normalmente como árboles rojo-negro.

Propiedades del contenedor


• De asociación
Los elementos en contenedores asociativos son referenciados por su clave y no por
su posición absoluta en el contenedor.
• Ordenado
Los elementos en el contenedor siguen un orden estricto en todo momento. Todos
los elementos insertados reciben una posición en este orden.
• Conjunto
El valor de un elemento es también la clave utilizada para identificarlo.
• Llaves unicas
No hay dos elementos en el contenedor que puedan tener claves equivalentes.
• Asignador-consciente
El contenedor utiliza un objeto de asignación para manejar dinámicamente sus
necesidades de almacenamiento.

El algoritmo de inserción de elementos para la estructura set está construido


de manera tal que si se trata de agregar a la lista un elemento que ya existe la
inserción es ignorada.
MultiSet

Los conjuntos
múltiples son un tipo
de contenedores
asociativos similares
a los establecidos,
con la excepción de
que varios elementos
pueden tener los
mismos valores. Son contenedores que almacenan elementos siguiendo un
orden específico, y donde múltiples elementos pueden tener valores
equivalentes.

Hay varias formas de std::set<int> sut;


buscar un valor dado sut.insert(10);
en std::set o en
sut.insert(15);
std::multiset :
sut.insert(22);

sut.insert(3); // contains 3, 10, 15, 22


Para obtener el
iterador de la
primera aparición de auto itS = sut.find(10); // the value is found, so *itS == 10
una clave, se puede itS = sut.find(555); // the value is not found, so itS == sut.end()
usar la función find()
. Devuelve end() si la std::multiset<int> msut;
clave no existe. sut.insert(10);

sut.insert(15);
Internamente, los
sut.insert(22);
elementos de un
conjunto múltiple sut.insert(15);

siempre se ordenan sut.insert(3); // contains 3, 10, 15, 15, 22

siguiendo un criterio
de ordenamiento auto itMS = msut.find(10);
débil estricto
específico indicado
por su objeto de comparación interno (del tipo Comparación).
Los conjuntos múltiples se implementan normalmente como árboles de
búsqueda binarios.

Los contenedores de conjuntos múltiples generalmente son más lentos que los
contenedores de múltiples conjuntos desordenados para acceder a elementos
individuales por su clave, pero permiten la iteración directa en subconjuntos
según su orden.

Map

Los mapas se utilizan para replicar matrices asociativas. Los mapas contienen
un par de clave-valor ordenado, en el que cada clave es única y no se puede
cambiar, y se puede insertar o eliminar, pero no se puede modificar. El valor
asociado a las claves puede ser alterado. Podemos buscar, eliminar e insertar
en un mapa dentro de la complejidad de tiempo O(n).

Por ejemplo: un mapa de


estudiantes donde el
número de rollo es la clave y
el nombre es el valor se
puede representar
gráficamente como:

Observe que las claves están ordenadas en orden ascendente, porque los
mapas siempre ordenan sus claves en orden. En caso de que las claves sean
de tipo cadena, se ordenan lexicográficamente.
Multimap

Los multimap son


contenedores
asociativos que
almacenan
elementos formados
por una combinación
de un valor de clave y
un valor asignado,
siguiendo un orden
específico, multimap es similar al map, con una adición de que varios
elementos pueden tener las mismas claves. En lugar de que cada elemento sea
único, el par de valor clave y valor asignado debe ser único en este caso.

Propiedades del contenedor

De asociación
Los elementos en contenedores asociativos son referenciados por su clave y
no por su posición absoluta en el contenedor.
Ordenado
Los elementos en el contenedor siguen un orden estricto en todo momento.
Todos los elementos insertados reciben una posición en este orden.
Map
Cada elemento asocia una clave a un valor asignado: las claves están
destinadas a identificar los elementos cuyo contenido principal es el valor
asignado.
Múltiples claves equivalentes
Múltiples elementos en el contenedor pueden tener claves equivalentes.
Asignador-consciente
El contenedor utiliza un objeto de asignación para manejar dinámicamente
sus necesidades de almacenamiento.

También podría gustarte