Publi

Almacenando elementos a pares en C++

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.

También podría interesarte...

Leave a Reply