En numerosas ocasiones necesitamos almacenar dos datos de diferente o igual tipo bajo la misma variable. Es más, en ocasiones estarán relacionados y no debemos separarlos o no tendría sentido.
La forma más inmediata es almacenar cada dato por su lado y diseñar los algoritmos de modo que siempre vayan los dos datos juntos, aunque tendremos un problema:
- Será difícil de mantener, tenemos siempre que asegurar que los datos siempre vayan juntos.
- Tendríamos que crear más documentación, o el que venga detrás de nosotros a hacer el programa lo pasará mal.
- Debemos crear funciones / métodos para manejar los datos.
De todas formas, C++ , en la biblioteca estándar contienen muchas cosas ya hechas y esta es una de ellas; utilizando la clase pair podemos hacer fácilmente la asignación / comparación / lectura de pares de datos. De la siguiente manera:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <iostream> using namespace std; int main() { pair<int,string> p; p.first=23; p.second="Probandoooo..."; cout << p.first << endl; cout << p.second << endl; p = make_pair(10, "Segunda prueba"); cout << p.first << endl; cout << p.second << endl; return 0; } |
Fácilmente podremos crear una instancia de pair, especificando los tipos de dato a almacenar y asignarle los datos (para los ejemplos utilizaré los tipos int y string; aunque puede ser cualquier tipo de dato, clases, etc:
- Desde el mismo constructor: pair
p(999, «Dato de ejemplo»); - Desde los atributos first y second (como en el ejemplo)
- Con la función make_pair(), en la que podemos introducir los objetos directamente
De esta forma, tal vez queramos introducir elementos de configuración, o asignar elementos de tipo clave=>valor, asignar un identificador a un elemento, o símplemente pasar dos datos juntos con un mismo elemento.
Pero si lo que en realidad queremos es almacenar un conjunto de datos (claves y valores) podemos utilizar map o multimap. El objetivo es introducir muchos tipos de elementos con su equivalencia (siendo ésta otro tipo de elemento distinto):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include <iostream> #include <map> using namespace std; int main() { map <int, string> m; map <int, string>::iterator i; // Forma 1 m.insert(pair<int, string>(10, "Elemento numero diez")); // Forma 2 m[20]="Elemento numero veinte"; // Forma 3 m.insert(m.begin(), pair<int, string>(30, "Elemento numero treinta")); // Insertamos más elementos m[40]="Elemento numero cuarenta"; m[50]="Elemento numero cincuenta"; m[60]="Elemento numero sesenta"; m[70]="Elemento numero ochenta"; // Listamos los elementos for (i=m.begin(); i!=m.end(); i++) { cout << "Elemento " << i->first << " = " << i->second << endl; } cout << endl; // Buscamos un elemento i=m.find(30); cout << "Elemento 30 => "<<i->second<<endl; cout << endl; // Buscamos un elemento de otra forma cout << "Elemento 40 => "<<m[40]<<endl; cout << endl; // Cuando un elemento no existe... i=m.find(35); if (i==m.end()) cout << "Elemento no existe" <<endl; else cout << "Elemento 35 => " << i->second <<endl; // Devuelve un elemento vacío (o recién construido) cout << "Elemento 55: "<< m[55] << endl; return 0; } |
Para escribir un poco menos a la hora de definir los tipos podemos utilizar typedef:
1 2 3 4 5 6 7 8 9 | typedef map <int, string> mis; // Map Int String typedef pis <int, string> mis; // Pair Int String int main() { mis m; mis::iterator m; m.insert(pis(10, "Cadena")); } |
O podemos utilizar el #define de toda la vida:
1 2 3 4 5 6 7 8 9 | #define is int, string int main() { map<is> m; map<is>::iterator i; m.insert(pair<is>(10, "Elemento numero diez")); } |
Aunque tendremos que tener cuidado con lo que pongamos con #define ya que los cambios serán globales.
Leave a Reply