In un articolo precedente abbiamo parlato dei contenitori sequenziali di STL ( Standard Template Library ) come i vettori, le deque ed altro, in questo nuovo articolo prendiamo in esame gli altri tipi di contenitori, quelli associativi, di cui fanno parte set e multiset, map e multimap. I set e multiset contengono elementi semplici, i map e multimap contengono coppie chiave-valore e sono equivalenti ai dizionari o array associativi di altri librerie e linguaggi. I set ed i map non ammettono elementi ripetuti, mentre i multiset ed i multimap possono contenerne e vengono inseriti a seconda dell’ordine di inserimento.
Tutti i contenitori associativi di STL sono implementati utilizzando una variante della struttura ad alberi binari, gli alberi red-black che consentono di tenere ordinati gli elementi all’interno della struttura. Gli alberi binari hanno sempre un tempo di ricerca logaritmico: il logaritmo in base 2 di 1000 vale circa 10, il che significa che con al massimo 10 confronti si riesce a trovare un elemento su 1000 e con 20 confronti si trova un elemento fra un milione.
#include <iostream>
#include <set>
using namespace std;
int main(int argc, char* argv[])
{
char c;
set<int> s;
s.insert(34);
s.insert(12);
s.insert(11);
s.insert(23);
s.insert(24);
s.insert(15);
copy(s.begin(), s.end(),
ostream_iterator<int>(cout, "\n"));
cout << endl;
cin >> c;
return 0;
}
Come vi avevo detto i contenitori associativi contengono gli elementi in maniera ordinata al contrario delle hash table, ecco perché trovare un valore al loro interno è molto veloce.
#include <iostream>
#include <set>
#include <time.h>
using namespace std;
int main(int argc, char* argv[])
{
char c;
int i;
set<int& s;
set<int>::iterator it;
srand((unsigned int)time(NULL));
for (i = 0; i < 3000; ++i)
s.insert(rand() % 5000 + 1);
s.count(i);
cout << "Abbiamo inserito " <<
i << " numeri interi" << endl << endl;
it = s.find(75);
if (it != s.end())
cout << "Abbiamo estratto il 75" << endl;
else
cout << "Non abbiamo estratto il 75" << endl;
cout << endl; cin >> c;
return 0;
}
Le map, come abbiamo detto in precedenza, sono formate da coppie chiave-valore e quindi risultano estremamente utili ad esempio nei lavori su piano cartesiano della geometria analitica oppure per tenere traccia dell’altezza di alcune persone.
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
char c;
string s;
map m;
map::iterator it;
m.insert(pair("Mario", 1.84));
m.insert(pair("Simone", 1.72));
m.insert(pair("Enrico", 1.75));
m.insert(pair("Patrizia", 1.68));
m.insert(pair("Cesare", 1.90));
cout << "I nostri amici:" << endl;
for (it = m.begin(); it != m.end(); ++it)
cout << (*it).first << endl;
cout << endl << "Digita il nome per sapere l'altezza"
<< endl;
cin >> s;
it = m.find(s);
if (it == m.end())
cout << "Amico non trovato" << endl;
else
cout << "L'altezza di " << s << ": " << (*it).second
<< endl;
cout << endl;
cin >> c;
return 0;
}
Ho cercato di creare degli esempi molto semplici e che vi mostrino come si programma con questi contenitori che sono veramente potenti per la gestione dei dati in memoria. Per domande o spiegazioni varie sono a vostra disposizione nel forum.


